代码之家  ›  专栏  ›  技术社区  ›  cdub

使用Javascript/jQuery和C#将SVG转换为PNG进行下载

  •  1
  • cdub  · 技术社区  · 6 年前

    我在页面上有一个svg图像。然后,用户单击一个链接,调用该链接以获取toDataUrl():

                console.log('Processing svg for NOT Internet Explorer');
                var svgText = $("#div-surrounding-svg-element").html();
                var d3Canvas = document.getElementById("d3-canvas");
                d3Canvas.width = 2000;
                d3Canvas.height = 300;
                var ctxt = d3Canvas.getContext("2d");
                // make canvas background
                ctxt.fillStyle = "#fff";
                ctxt.fillRect(0, 0, d3Canvas.width, d3Canvas.height);
    
                var svg = new Blob([svgText], { type: "image/svg+xml;charset=utf-8" });
                var domURL = self.URL || self.webkitURL || self;
                var url = domURL.createObjectURL(svg);
                var img = new Image();
    
                img.onload = function ()
                {
                    ctxt.drawImage(this, 0, 0);
                    domURL.revokeObjectURL(url);
                    var dataUrl = d3Canvas.toDataURL();
                    // $('#download-chart-dataUrl').val(dataUrl);
                    // var downloadExcelForm = $('#download-chart-form');
                    // downloadExcelForm.submit();
    
                    // $('#download-chart-form').submit();
                    DownloadPNG(dataUrl);
                };
    
                img.src = url;
            }
    

    DownloadPNG向服务器发送邮件,C执行以下操作:

            var base64Data = Regex.Match(dataUrl, @"data:image/(?<type>.+?),(?<data>.+)").Groups["data"].Value;
            var binData = Convert.FromBase64String(base64Data);
    
            using (var stream = new MemoryStream(binData))
            {
                var tempFolder = ConfigurationManager.AppSettings["tempFilesDirectory"];
                var bitmap = new Bitmap(stream);
    
                var folder = Server.MapPath(tempFolder);
                var imagePath = folder + $"/{Guid.NewGuid().ToString()}.png";
                bitmap.Save(imagePath);
    
                //return File(imagePath, "image/png", "Chart.png");
                Response.Clear();
                Response.AddHeader("Content-Disposition", "attachment;filename=Chart.png");
                Response.WriteFile(imagePath);
                Response.End();
            }
    

    我得到了一个纯白色png而不是我想要的图像。我错过了什么?谢谢。

    1 回复  |  直到 6 年前
        1
  •  5
  •   Alex Nikulin    6 年前

    你不需要任何服务器端下载png)请看一个例子 附笔。 在2k18中使用jquery进行dom操作是一种“低级趣味”,请使用dom api)

    更新: 我已经将querySelector添加到SVG的SVG子级中,并将SVG序列化代码。

    downloadPng=function(){
       var img = new Image();
       img.onload = function (){
    	var canvas = document.createElement("canvas");
    	canvas.width = img.naturalWidth;
    	canvas.height = img.naturalHeight;
    	var ctxt = canvas.getContext("2d");
    	ctxt.fillStyle = "#fff";
    	ctxt.fillRect(0, 0, canvas.width, canvas.height);
            ctxt.drawImage(img, 0, 0);
    	var a = document.createElement("a");
    	a.href = canvas.toDataURL("image/png");
    	a.download = "image.png"
    	document.body.appendChild(a);
    	a.click();
    	document.body.removeChild(a);
       };
       var innerSvg = document.querySelector("#div-surrounding-svg-element svg svg");
       var svgText = (new XMLSerializer()).serializeToString(innerSvg);
       img.src = "data:image/svg+xml;utf8," + encodeURIComponent(svgText);
    }
    <div id="div-surrounding-svg-element">
      <svg id="inner-svg" height="100" width="500" xmlns="http://www.w3.org/2000/svg">
        <svg height="100" width="500" xmlns="http://www.w3.org/2000/svg">
          <ellipse cx="240" cy="50" rx="220" ry="30" style="fill:green" />
        </svg>
        <ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" />
      </svg>
    </div>
    <button onclick="downloadPng()">download</button>