"CanvasRenderingContext2D" 将 jpeg 转换为数据时出错-url
"CanvasRenderingContext2D" error at converting jpeg to data-url
我在开发我的 chrome 应用程序,内容安全政策令人不安。我想从 json (string/object/array 我不知道) 获取 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.
我希望有人能帮助我:)
抱歉我的英语不好
您的代码有 3 个问题:
正如@A.Wolff 推断的那样,您的 img 无效。 Canvas 需要完整的 Image 对象才能绘制,而不仅仅是 URL。所以你将不得不 "new up" 一个图像对象 var img=new Image();
图像是异步加载的,因此您必须将 drawImage
和 toDataURL
放在 img.onload
回调中。这允许图像在您尝试使用它之前被完全加载。这也意味着您还必须将所有使用 dataURL 的代码放在 onload 回调中,而不是 return dataURL
。 (是的,我知道,那很乱,但你必须那样做,否则图像没有完全加载)
出于安全原因,要使用 toDataURL
,您的图片必须与您的网页托管在同一域中。如果它们是不同的域,toDataURL
将因安全错误而失败。此安全问题是一个涉及的主题,因此您可以在此处了解避免安全错误的必要条件:http://enable-cors.org/
...并且: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>
我在开发我的 chrome 应用程序,内容安全政策令人不安。我想从 json (string/object/array 我不知道) 获取 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.
我希望有人能帮助我:) 抱歉我的英语不好
您的代码有 3 个问题:
正如@A.Wolff 推断的那样,您的 img 无效。 Canvas 需要完整的 Image 对象才能绘制,而不仅仅是 URL。所以你将不得不 "new up" 一个图像对象
var img=new Image();
图像是异步加载的,因此您必须将
drawImage
和toDataURL
放在img.onload
回调中。这允许图像在您尝试使用它之前被完全加载。这也意味着您还必须将所有使用 dataURL 的代码放在 onload 回调中,而不是return dataURL
。 (是的,我知道,那很乱,但你必须那样做,否则图像没有完全加载)出于安全原因,要使用
toDataURL
,您的图片必须与您的网页托管在同一域中。如果它们是不同的域,toDataURL
将因安全错误而失败。此安全问题是一个涉及的主题,因此您可以在此处了解避免安全错误的必要条件:http://enable-cors.org/
...并且: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>