Javascript 如何在Firefox中处理边界处的getImageData?
我目前正在编写一个小的绘图应用程序,它需要为其涂抹和模糊工具访问像素数据,并且在Firefox中遇到了HTML5画布API的一个棘手问题。显然,它没有实现规范中定义的getImageData。画布外的像素必须返回为透明黑色 这在FF中不会发生(在FF 3.6和4 beta 9中测试)。相反,它将给出如下错误:指定了无效或非法的字符串“code:”12 请注意,这在Chrome中似乎可以正常工作 我想这意味着我必须实现一些额外的代码来解决这个限制。我使用以下代码绕过了这个问题:Javascript 如何在Firefox中处理边界处的getImageData?,javascript,html,firefox,html5-canvas,getimagedata,Javascript,Html,Firefox,Html5 Canvas,Getimagedata,我目前正在编写一个小的绘图应用程序,它需要为其涂抹和模糊工具访问像素数据,并且在Firefox中遇到了HTML5画布API的一个棘手问题。显然,它没有实现规范中定义的getImageData。画布外的像素必须返回为透明黑色 这在FF中不会发生(在FF 3.6和4 beta 9中测试)。相反,它将给出如下错误:指定了无效或非法的字符串“code:”12 请注意,这在Chrome中似乎可以正常工作 我想这意味着我必须实现一些额外的代码来解决这个限制。我使用以下代码绕过了这个问题:
getImageDataAround: function(p, r) {
p = this._toAbsolute(p);
r = this._toAbsolute(r);
p = p.sub(r);
var d = r * 2;
var width = d;
var height = d;
// XXX: FF hack
if(navigator.userAgent.indexOf('Firefox') != -1) {
if(p.x < 0) {
width += p.x;
p.x = 0;
}
if(p.y < 0) {
height += p.y;
p.y = 0;
}
var x2 = p.x + width;
if(x2 >= this.width) {
width = d - (x2 - this.width);
}
var y2 = p.y + height;
if(y2 >= this.height) {
height = d - (y2 - this.height);
}
if((width != d) || (height != d)) {
// XXX: not ideal but at least this won't give any
// errors
return this.ctx.createImageData(d, d);
}
}
return this.ctx.getImageData(p.x, p.y, width, height);
},
getImageDataAround:函数(p,r){
p=这个。_表示绝对(p);
r=这个。\ u到绝对值(r);
p=p.sub(r);
var d=r*2;
var宽度=d;
var高度=d;
//XXX:FF黑客
if(navigator.userAgent.indexOf('Firefox')!=-1){
如果(p.x<0){
宽度+=p.x;
p、 x=0;
}
如果(p.y<0){
身高+=年平均值;
p、 y=0;
}
var x2=p.x+宽度;
如果(x2>=此宽度){
宽度=d-(x2-此宽度);
}
变量y2=p.y+高度;
如果(y2>=此高度){
高度=d-(y2-该高度);
}
如果((宽度!=d)|(高度!=d)){
//XXX:不理想,但至少这不会给你任何帮助
//错误
返回这个.ctx.createImageData(d,d);
}
}
返回这个.ctx.getImageData(p.x,p.y,宽度,高度);
},
这并不酷,因为我将一堆空像素返回给调用者。像在规范中一样返回结果会更好
只是澄清一下,代码是上下文API的一部分,它包装了真实的上下文,并提供了一些额外的功能(相对坐标等)。这可能解释了像这样的东西,宽度等的来源
麻烦的是XXX部分。我只是需要一些方法来返回符合规范的图像数据。欢迎提供任何有关如何返回图像数据的想法。:) 也许您可以创建一个大小为d×d的画布,并在其上绘制原始画布的适当部分?遗憾的是,您无法直接绘制原始画布,因为您遇到了相同类型的边界检查代码,因此您必须找出重叠部分 你应该考虑嗅探而不是火狐。< /P>
顺便说一句,我是Mozilla。我最后用下面的代码片段解决了这个问题。希望有人觉得它有用
var getImageDataAround = function(ctx, p, r) {
// ctx: HTML5 Canvas 2D context
// p: {x: 23, y: 37}
// r: radius in px
// FF fails with fractional values
p.x = Math.round(p.x);
p.y = Math.round(p.y);
r = parseInt(r);
p.x -= r;
p.y -= r;
var d = r * 2;
var width = d;
var height = d;
// FF fails at bounds
if(navigator.userAgent.indexOf('Gecko') != -1) {
var xOffset = 0;
var yOffset = 0;
if(p.x < 0) {
xOffset = -p.x;
width += p.x;
p.x = 0;
}
if(p.y < 0) {
yOffset = -p.y;
height += p.y;
p.y = 0;
}
var x2 = p.x + width;
if(x2 >= ctx.canvas.width) {
width = d - (x2 - ctx.canvas.width);
}
var y2 = p.y + height;
if(y2 >= ctx.canvas.height) {
height = d - (y2 - ctx.canvas.height);
}
if((width != d) || (height != d)) {
var data = ctx.createImageData(d, d);
if(xOffset >= d || yOffset >= d ||
width < 1 || height < 1) {
// totally outside of bounds
return data;
}
var originalData = ctx.getImageData(p.x, p.y,
width, height);
var pos = 4 * (xOffset + d * yOffset);
var dataLen = 4 * d * (yOffset + height);
for(var originalPos = 0, x = xOffset;
pos < dataLen;
pos += 4, originalPos += 4, x++) {
if(x == d) {
x = xOffset;
pos += xOffset * 4;
}
if(xOffset <= x && x < width + xOffset) {
data.data[pos] = originalData.data[originalPos];
data.data[pos + 1] = originalData.data[originalPos + 1];
data.data[pos + 2] = originalData.data[originalPos + 2];
data.data[pos + 3] = originalData.data[originalPos + 3];
}
else {
originalPos -= 4;
}
}
return data;
}
}
return ctx.getImageData(p.x, p.y, width, height);
}
var getImageDataAround=函数(ctx,p,r){
//ctx:HTML5画布2D上下文
//p:{x:23,y:37}
//r:以px为单位的半径
//FF因分数值而失败
p、 x=数学四舍五入(p.x);
p、 y=数学轮(p.y);
r=parseInt(r);
p、 x-=r;
p、 y-=r;
var d=r*2;
var宽度=d;
var高度=d;
//FF在边界处失败
if(navigator.userAgent.indexOf('Gecko')!=-1){
var xOffset=0;
var yOffset=0;
如果(p.x<0){
xOffset=-p.x;
宽度+=p.x;
p、 x=0;
}
如果(p.y<0){
yOffset=-p.y;
身高+=年平均值;
p、 y=0;
}
var x2=p.x+宽度;
如果(x2>=ctx.canvas.width){
宽度=d-(x2-ctx.canvas.width);
}
变量y2=p.y+高度;
如果(y2>=ctx.canvas.height){
高度=d-(y2-ctx.canvas.height);
}
如果((宽度!=d)|(高度!=d)){
var data=ctx.createImageData(d,d);
如果(xOffset>=d | | yOffset>=d||
宽度<1 | |高度<1){
//完全越界
返回数据;
}
var originalData=ctx.getImageData(p.x,p.y,
宽度、高度);
var pos=4*(xOffset+d*yOffset);
var dataLen=4*d*(偏移量+高度);
对于(var originalPos=0,x=xOffset;
pos 如果(xOffset是的。我想没有其他办法了…很遗憾他们还没有修复它(错误报告是从2007年开始的!)。我将把这个问题保留一段时间,以获得一些其他想法。如果没有任何结果,我将接受你的回答。:)嗅探的好处!