挑战:修复 Canvas 插件以使用 CORS?
Challenge: Fix a Canvas plugin to work with CORS?
我正在向任何 Canvas 专家寻求帮助!
我需要修复 jQuery/Canvas 插件。我在 Canvas 方面很弱。
基本上我希望能够模糊图像,我已经使用这个 Canvas 脚本完成了:
http://www.quasimondo.com/BoxBlurForCanvas/FastBlur2Demo.html
https://github.com/Quasimondo/QuasimondoJS/blob/master/blur/StackBoxBlur.js
但它不适用于托管在另一个域上的图像(我在 app.example.com 和 api.example.com 上拥有所有内容)。所以我需要更新它以尊重 CORS/crossOrigin。我与原始开发人员有 documented the issue,但我怀疑他是否会修复它(自从他以主要方式触及它以来已有多年)。
Canvas 大师的工作时间可能很轻松。
插件通过调用这个来工作:
stackBoxBlurImage( sourceImageID, targetCanvasID, radius, blurAlphaChannel, iterations );
我试过这样做:
var img = document.getElementById( imageID );
img.crossOrigin = '';
var w = img.naturalWidth;
var h = img.naturalHeight;
但这并不能解决问题。
理想情况下,我希望能够输入 $('.image')
(或只是 URL,因为我不需要 un-blurred 图片弄乱 DOM) 和 $('.canvas')
元素,而不是两个 ID。这样,在事件中切换模糊图像可能会更容易一些(比如在菜单打开时模糊图像等)。
如果重要的话,我会在 Ember 应用程序中使用它。我也不想使用某种 PHP 代理脚本,这似乎是一种破解方法。
更新
我在此处添加了一个中断示例:
http://dev.rickanddrew.com/
图片在这里。如果您查看响应 header,我认为 CORS 设置正确:
http://image.rickanddrew.com/image.jpg
回答
感谢下面的肯,我明白了!这就是我现在的方式 运行:
function stackBoxBlurImage( imageURL, $canvasObj, radius, blurAlphaChannel, iterations )
{
// Cache vars
var img = document.createElement('img');
var canvas = $canvasObj[0];
// Make it work with CORS
img.crossOrigin = '';
img.src = imageURL;
// Wait till image loads
img.onload = function(e) {
// Setup image vars
var w = img.naturalWidth;
var h = img.naturalHeight;
// Setup Canvas size
canvas.style.width = w + "px";
canvas.style.height = h + "px";
canvas.width = w;
canvas.height = h;
// Add image to Canvas
var context = canvas.getContext("2d");
context.drawImage(img, 0, 0, canvas.width, canvas.height);
context.clearRect( 0, 0, w, h );
context.drawImage( img, 0, 0 );
// Abort if radius is invalid
if ( isNaN(radius) || radius < 1 ) return;
// Blur!
stackBoxBlurCanvasRGB( canvas, 0, 0, w, h, radius, iterations );
};
}
谢谢!
#1 CORS 订单很重要
CORS 请求未正确使用。就像现在一样,设置了图像标签的 src
,然后在模糊脚本中设置了 crossOrigin
post:
function stackBoxBlurImage( imageID, canvasID, radius, blurAlphaChannel, iterations )
{
var img = document.getElementById( imageID ); // we already have the image.
img.crossOrigin = ''; // too late for this...
...
这将不起作用,因为必须先设置 crossOrigin
,然后再设置 图像 src
。 CORS 使用请求与 URL 请求一起发送(如果服务器不喜欢它,我们就没有图像...)。
所以要解决,要么将 crossOrigin
添加到 img 标签本身:
<img id="image" crossOrigin="anonymous" src="image.jpg">
或者如果您愿意或需要动态设置 src
,则在加载 JavaScript 之前不要设置 src
(在这种情况下,我建议动态创建图像元素,如嗯):
<img id="image">
然后:
var image = document.getElementById("image");
image.crossOrigin = "";
image.onload = blur;
image.src = "image.jpg";
function blur() {
stackBoxBlurImage( 'image', 'canvas', 30);
}
#2 负载很重要
脚本的调用方式也存在问题,这会阻止图像数据可用(新加载、无缓存等)。如果图片已经存在于缓存中,这个问题就更难检测了(虽然新用户在第一次加载时可能看不到任何东西......)。
改变这个:
jQuery(document).ready(function(){
stackBoxBlurImage( 'image', 'canvas', 30);
})
至:
$(window).load(function() {
stackBoxBlurImage( 'image', 'canvas', 30);
})
ready
只是表示DOM准备好了,不一定是图像数据。为此,必须使用 load
。
服务器也有一个有趣的响应,其中图像请求似乎被解释为纯文本。但我没有深入挖掘,因为上面的步骤应该首先解决(或者我只是眨了眨眼:)):
我正在向任何 Canvas 专家寻求帮助!
我需要修复 jQuery/Canvas 插件。我在 Canvas 方面很弱。
基本上我希望能够模糊图像,我已经使用这个 Canvas 脚本完成了: http://www.quasimondo.com/BoxBlurForCanvas/FastBlur2Demo.html
https://github.com/Quasimondo/QuasimondoJS/blob/master/blur/StackBoxBlur.js
但它不适用于托管在另一个域上的图像(我在 app.example.com 和 api.example.com 上拥有所有内容)。所以我需要更新它以尊重 CORS/crossOrigin。我与原始开发人员有 documented the issue,但我怀疑他是否会修复它(自从他以主要方式触及它以来已有多年)。
Canvas 大师的工作时间可能很轻松。
插件通过调用这个来工作:
stackBoxBlurImage( sourceImageID, targetCanvasID, radius, blurAlphaChannel, iterations );
我试过这样做:
var img = document.getElementById( imageID );
img.crossOrigin = '';
var w = img.naturalWidth;
var h = img.naturalHeight;
但这并不能解决问题。
理想情况下,我希望能够输入 $('.image')
(或只是 URL,因为我不需要 un-blurred 图片弄乱 DOM) 和 $('.canvas')
元素,而不是两个 ID。这样,在事件中切换模糊图像可能会更容易一些(比如在菜单打开时模糊图像等)。
如果重要的话,我会在 Ember 应用程序中使用它。我也不想使用某种 PHP 代理脚本,这似乎是一种破解方法。
更新
我在此处添加了一个中断示例: http://dev.rickanddrew.com/
图片在这里。如果您查看响应 header,我认为 CORS 设置正确: http://image.rickanddrew.com/image.jpg
回答
感谢下面的肯,我明白了!这就是我现在的方式 运行:
function stackBoxBlurImage( imageURL, $canvasObj, radius, blurAlphaChannel, iterations )
{
// Cache vars
var img = document.createElement('img');
var canvas = $canvasObj[0];
// Make it work with CORS
img.crossOrigin = '';
img.src = imageURL;
// Wait till image loads
img.onload = function(e) {
// Setup image vars
var w = img.naturalWidth;
var h = img.naturalHeight;
// Setup Canvas size
canvas.style.width = w + "px";
canvas.style.height = h + "px";
canvas.width = w;
canvas.height = h;
// Add image to Canvas
var context = canvas.getContext("2d");
context.drawImage(img, 0, 0, canvas.width, canvas.height);
context.clearRect( 0, 0, w, h );
context.drawImage( img, 0, 0 );
// Abort if radius is invalid
if ( isNaN(radius) || radius < 1 ) return;
// Blur!
stackBoxBlurCanvasRGB( canvas, 0, 0, w, h, radius, iterations );
};
}
谢谢!
#1 CORS 订单很重要
CORS 请求未正确使用。就像现在一样,设置了图像标签的 src
,然后在模糊脚本中设置了 crossOrigin
post:
function stackBoxBlurImage( imageID, canvasID, radius, blurAlphaChannel, iterations )
{
var img = document.getElementById( imageID ); // we already have the image.
img.crossOrigin = ''; // too late for this...
...
这将不起作用,因为必须先设置 crossOrigin
,然后再设置 图像 src
。 CORS 使用请求与 URL 请求一起发送(如果服务器不喜欢它,我们就没有图像...)。
所以要解决,要么将 crossOrigin
添加到 img 标签本身:
<img id="image" crossOrigin="anonymous" src="image.jpg">
或者如果您愿意或需要动态设置 src
,则在加载 JavaScript 之前不要设置 src
(在这种情况下,我建议动态创建图像元素,如嗯):
<img id="image">
然后:
var image = document.getElementById("image");
image.crossOrigin = "";
image.onload = blur;
image.src = "image.jpg";
function blur() {
stackBoxBlurImage( 'image', 'canvas', 30);
}
#2 负载很重要
脚本的调用方式也存在问题,这会阻止图像数据可用(新加载、无缓存等)。如果图片已经存在于缓存中,这个问题就更难检测了(虽然新用户在第一次加载时可能看不到任何东西......)。
改变这个:
jQuery(document).ready(function(){
stackBoxBlurImage( 'image', 'canvas', 30);
})
至:
$(window).load(function() {
stackBoxBlurImage( 'image', 'canvas', 30);
})
ready
只是表示DOM准备好了,不一定是图像数据。为此,必须使用 load
。
服务器也有一个有趣的响应,其中图像请求似乎被解释为纯文本。但我没有深入挖掘,因为上面的步骤应该首先解决(或者我只是眨了眨眼:)):