将jpeg转换为data-url时出现“CanvasRenderingContext2D”错误

时间:2015-02-14 11:37:53

标签: jquery canvas jpeg drawimage data-url

我在我的Chrome应用程序上工作,内容安全政策令人紧张。我想从json (我不知道的字符串/对象/数组)中获取jpeg图像,但csp每次都阻止了我。现在我知道数据链接更容易,所以I searched a converter

function getdt(img) {
    // Create an empty canvas element
    var canvas = document.createElement("canvas");

    // Copy the image contents to the canvas
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, img.width, img.height);

    // Get the data-URL formatted image.
    var dataURL = canvas.toDataURL("image/png");

    return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}

//Example
getdt('http://ms01.oe3.fm/oe3metafiles/Pictures/200/929203.22.jpg');

不幸的是,这不起作用。错误消息是这样的:

Uncaught TypeError: 
Failed to execute 'drawImage' on 'CanvasRenderingContext2D': 
No function was found that matched the signature provided.

我希望有人可以帮助我:) 抱歉我的英文不好

1 个答案:

答案 0 :(得分:1)

您的代码有3个问题:

  1. 正如@ A.Wolff所推断,你的img无效。 Canvas需要一个完整的Image对象来绘制,而不仅仅是一个URL。因此,您将不得不重新启动"图像对象var img=new Image();

  2. 图像是异步加载的,因此您必须将drawImagetoDataURL放在img.onload回调中。这样可以在尝试使用之前完全加载图像。这也意味着您必须将所有使用dataURL的代码放在onload回调中,而不是return dataURL。 (是的,我知道,这很麻烦,但你必须这样做,否则图像不能满载)

  3. 出于安全原因,要使用toDataURL,您的图片必须与您的网页托管在同一个域中。如果它们是不同的域,toDataURL将失败并出现安全错误。此安全问题是一个涉及的主题,因此您可以在此处了解避免安全错误所需的内容:http://enable-cors.org/

  4. ...而且:toDataURL的jpg编码使用image/jpeg,因此您需要更改注册表。

    此处您的代码已经过重构,并且使用的方式托管的图片无法创建安全错误:

    
    
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var cw=canvas.width;
    var ch=canvas.height;
    
    
    var img=new Image();
    img.crossOrigin='anonymous';
    img.onload=start;
    img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sun.png";
    function start(){
    
      canvas.width=img.width;
      canvas.height=img.height;
      ctx.drawImage(img,0,0);
      var dataURL=canvas.toDataURL(); // png is the default format
    
      dataURL=dataURL.replace(/^data:image\/(png|jpeg);base64,/, "");
    
      // Your dataURL is now available
      // Use it as desired
      alert('The dataURL is '+dataURL.length+' characters long ans starts with: '+dataURL.substring(0,20));
    
    }
    
    body{ background-color: ivory; padding:10px; }
    #canvas{border:1px solid red;}
    
    <canvas id="canvas" width=300 height=300></canvas>
    &#13;
    &#13;
    &#13;