You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SVG转Blob再生成imageUrl异常,无法渲染至Canvas求助

问题

我有一个文件输入框,需要将选中的文件转换为imageUrl后添加到Canvas中。发现SVG是特殊情况,需要先转为Blob再生成imageUrl,但Blob转换看似正常,生成的url却返回异常结果。

相关代码

JavaScript代码

function initiate() {
  var canvas = $("#canvas").get(0);
  var context = canvas.getContext("2d");
  var img = new Image();
  var imageSrcUrl;
  img.onload = function() {
    URL.revokeObjectURL(imageSrcUrl), {once: true}
    context.drawImage(
      img,
      0,
      0,
      img.width,
      img.height,
      0,
      0
    );
  }
  var extension = $("#logo").get(0).files[0].name.split('.').pop().toLowerCase();
  if(extension == 'svg') {
      var reader = new FileReader();
      reader.onload = function() {
          console.log(reader.result);
          var blob = new Blob([reader.result.toString()], {type: 'image/svg+xml'});
          console.log(blob);
          imageSrcUrl = URL.createObjectURL(blob);
          console.log(imageSrcUrl);
          img.src = imageSrcUrl;                  
      };
      reader.readAsText($("#logo").get(0).files[0]);
  } else {
      img.src = URL.createObjectURL(
        $("#logo").get(0).files[0]
      );
  }
 }

HTML代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<form id="form">
  Select file here
  <input type="file" id="logo">
</form>
<br><br>
Canvas goes here
<canvas width="400" height="200" id="canvas"></canvas>
<br><br>
<button onclick="initiate();">Get svg into canvas</button>

控制台日志

  • reader.result:< svg version="1.1" id="Laag_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 605.3 146.4" style="enable-background:new 0 0 605.3 146.4;" xml:space="preserve">...(为格式调整添加了开头空格)
  • blob:Blob { size: 50643, type: "image/svg+xml" }
  • imageSrcUrl:blob:https://ourdomain.be/a64506fb-00db-459a-8e17-1aab67dadd9b

解决方案

你的代码存在两个核心问题,导致SVG无法正常加载到Canvas:

1. 错误的Blob URL回收时机与语法

img.onload中的URL.revokeObjectURL(imageSrcUrl), {once: true}是错误写法:逗号运算符会忽略{once: true}参数,且你在图片刚触发load事件就立即回收了Blob URL——此时图片还未完成绘制,URL被回收后浏览器无法读取SVG内容,导致加载失败。

正确做法是:使用addEventListener绑定单次触发的load事件,在绘制完成后再回收URL。

2. SVG内容的无效处理

控制台日志显示reader.result开头有额外单引号,这会导致SVG格式无效;另外reader.result本身就是字符串,无需调用toString(),多余的转换可能引入意外格式问题。

修正后的代码

JavaScript代码

function initiate() {
  var canvas = $("#canvas").get(0);
  var context = canvas.getContext("2d");
  var img = new Image();
  var imageSrcUrl;

  // 绑定单次触发的load事件,确保事件只执行一次
  img.addEventListener('load', function() {
    // 绘制完成后再回收Blob URL
    URL.revokeObjectURL(imageSrcUrl);
    // 适配Canvas尺寸绘制图片
    context.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
  }, {once: true});

  // 校验是否选择了文件
  var fileInput = $("#logo").get(0);
  if (!fileInput.files || fileInput.files.length === 0) {
    alert('请先选择文件');
    return;
  }
  var file = fileInput.files[0];
  var extension = file.name.split('.').pop().toLowerCase();

  if (extension === 'svg') {
    var reader = new FileReader();
    reader.onload = function() {
      // 清理SVG内容首尾的空格和可能的引号,确保格式有效
      var svgContent = reader.result.trim().replace(/^['"]|['"]$/g, '');
      var blob = new Blob([svgContent], {type: 'image/svg+xml'});
      imageSrcUrl = URL.createObjectURL(blob);
      img.src = imageSrcUrl;
    };
    reader.readAsText(file);
  } else {
    imageSrcUrl = URL.createObjectURL(file);
    img.src = imageSrcUrl;
  }
}

额外优化说明

  • 添加了文件选择校验,避免未选文件时触发错误
  • 绘制时指定了Canvas目标宽高,确保SVG适配Canvas尺寸显示
  • 清理SVG内容的首尾冗余字符,避免格式错误导致加载失败

内容的提问来源于stack exchange,提问作者Mats Raemen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:40:34