Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何获取特定对象上的图像数据?_Javascript_Html_Canvas_Getimagedata - Fatal编程技术网

Javascript 如何获取特定对象上的图像数据?

Javascript 如何获取特定对象上的图像数据?,javascript,html,canvas,getimagedata,Javascript,Html,Canvas,Getimagedata,在画布中,我创建了一个2d上下文。在这种情况下。。。有一个函数。。。我能够创建一些“圆形对象”。现在,我想得到的是单个圆对象的图像数据,而不是整个上下文的图像数据 在下面的代码中,你可以看到我的愿望被注释掉了 var c = document.getElementById('canvas'); var ctx = c.getContext('2d'); var circle = function (X,Y) { var that = this; that.X = X;

在画布中,我创建了一个2d上下文。在这种情况下。。。有一个函数。。。我能够创建一些“圆形对象”。现在,我想得到的是单个圆对象的图像数据,而不是整个上下文的图像数据

在下面的代码中,你可以看到我的愿望被注释掉了

var c = document.getElementById('canvas');
var ctx = c.getContext('2d');

var circle = function (X,Y) {
    var that = this;
    that.X = X;
    that.Y = Y;
    that.clicked = function(e) {
        //
        //
        //!!!!!!!!!!!!!!
        // Code below works fine, on context level
        imgData = ctx.getImageData(e.pageX, e.pageY, 1, 1);
        //
        // Code below is at the level of the circle, that's what I want, but isn't working
        imgData = that.getImageData(e.pageX, e.pageY, 1, 1);
        //!!!!!!!!!!!!!!
        //
        //
        alert(imgData.data[3]);
    }
    that.draw = function () {
        ctx.save();
        ctx.translate(that.X, that.Y);
        ctx.fillStyle = '#33cc33';
        ctx.beginPath();
        ctx.arc(0, 0, 50, 0, 2 * Math.PI);
        ctx.fill();
        ctx.stroke();
        ctx.restore();
    }
}
var circles = new Array();
circles.push(new circle(50,50));
document.addEventListener('click',function() {
    circles.forEach(function(circ,index){
        circ.clicked();
    });
})
那么,如何获取特定对象的图像数据呢

编辑:
我知道我需要先画一个圆,我以后在我的代码中会这样做,但是如果我在上下文中有一个背景矩形,当我单击圆旁边时,它会得到背景矩形的imageData,当我想返回alpha rgba的0值时。

这是因为
不是
CanvasGraphicsContext
。尝试:

that.draw();
imgData = ctx.getImageData(e.pageX, e.pageY, 1, 1);

请记住,Canvas是一个位图图形工具。在单个上下文中绘制的任何内容都将成为同一对象的一部分。您无法为您在画布上绘制的每个“对象”获取单独的图像数据。。。它是画的。。。扁平的。。。只要点击
draw()
,就可以将该位图转换到这些像素位置

唯一的方法是创建单独的画布上下文,并将其覆盖在彼此之上。使用KineticJS()之类的库可以更好地处理这一问题。唯一的其他选择是使用面向对象的绘图工具,如SVG(通过Raphael.js,例如:),它在图形空间中保留单独的对象


有关getImageData的参考信息,请参见

您可以使用三角学,而不是使用getImageData查找颜色

例如,如果有这样定义的圆:

var centerX=150;
var centerY=150;
var radius=20;
var circleColor="red";
// returns true if x,y is inside the red circle
isXYinCircle(140,140,centerX,centerY,radius);

function isXYinCircle(x,y,cx,cy,r){
    var dx=x-cx;
    var dy=y-cy;
    return(dx*dx+dy*dy<=r*r);
}
然后你可以测试是否有x,y在圆内,如下所示:

var centerX=150;
var centerY=150;
var radius=20;
var circleColor="red";
// returns true if x,y is inside the red circle
isXYinCircle(140,140,centerX,centerY,radius);

function isXYinCircle(x,y,cx,cy,r){
    var dx=x-cx;
    var dy=y-cy;
    return(dx*dx+dy*dy<=r*r);
}
//如果x,y在红色圆圈内,则返回true
Isxyincrcle(140140,中心x,中心y,半径);
函数isxyincrcle(x,y,cx,cy,r){
var dx=x-cx;
var-dy=y-cy;

返回(dx*dx+dy*dy到此,您需要将所有图形记录为“阴影画布”。最常用的方法是创建形状对象并将其存储在例如数组中:

  • 在画布上绘制形状
  • 记录其类型、位置、尺寸、颜色和方向,并作为对象存储,然后将该对象推送到阵列中
当需要将孤立的形状或对象作为图像时:

  • 获取鼠标位置(如果要单击对象以选择它)
  • 迭代对象数组以查看哪个对象被“命中”
  • 创建该形状尺寸的临时画布
  • 将形状绘制到临时画布中
  • 将数据提取为图像(
    ctx.getImageData(x,y,w,h)
    canvas.toDataURL()
当您需要调整画布大小时,只需迭代所有对象并重新绘制它们。您甚至可以使用此方法序列化数据以进行存储

对象的示例可以是:

function Rectangle(x, y, w, h, fill, stroke) {
    this.x = x;
    this.y = y;
    this.width = w;
    this.height = h;
    this.fill = fill;
    this.stroke = stroke;
}
您可以扩展此对象以将其自身渲染到画布,并为您提供一个与其他形状隔离的位图。将此添加到上述代码中:

Rectangle.prototype.render = function(ctx) {
    if (this.fill) {                  /// fill only if fill is defined
        ctx.fillStyle = this.fill;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
    if (this.stroke) {                /// stroke only if stroke is defined
        ctx.strokeStyle = this.stroke;
        ctx.strokeRect(this.x, this.y, this.width, this.height);
    }
}

Rectangle.prototype.toBitmap = function() {

    var tcanvas = document.createElement('canvas'),  /// create temp canvas
        tctx = tcanvas.getContext('2d');             /// temp context

    tcanvas.width = this.width;         /// set width = shape width
    tcanvas.height = this.height;
    tctx.translate(-this.x, -this.y);   /// make sure shape is drawn at origin

    this.render(tcxt);                  /// render itself to temp context

    return tcanvas.toDataURL();         /// return image (or use getImageData)
}
您只需绘制形状,根据位置等创建对象:

var rect = new Rectangle(x, y, w, h, fillColor, strokeColor);

myShapeArray.push(rect);
当需要渲染形状时:

for(var i = 0, shape; shape = myShapeArray[i++];)
    shape.render(ctx);
当您需要获取其位图时(您可以通过单击鼠标提前检索其索引):

当然,你也可以制作类似的圆、线等物体


希望这有帮助!

首先,我创建了两个画布元素。1个用于显示,1个用于计算像素数据

var c = document.getElementById('canvas');
var c2 = document.getElementById('canvas2');
var ctx = c.getContext('2d');
var ctx2 = c2.getContext('2d');

var width = window.innerWidth,
    height = window.innerHeight;

c.width = ctx.width = c2.width = ctx2.width = width;
c.height = ctx.height = c2.height = ctx2.height = height;
然后我用我的函数来创建一个图像

function Afbeelding(src, X, Y, W, H) {
    var that = this;
    that.X = X;
    that.Y = Y;
    that.W = W;
    that.H = H;
    that.onClick = function () { };
    that.image = new Image(that.W, that.H);
    that.image.src = src;
    that.draw = function (context) { 
        context = (typeof context != 'undefined') ? context : ctx;
        context.save();
        context.translate(that.X, that.Y);
        context.drawImage(that.image, 0, 0, that.W, that.H);
        context.restore();
    }
当触发document.click事件时,将调用下一个函数(在Afbeelding函数中):

that.clicked = function (e) {
    if ((e.pageX > that.X - (that.W / 2) && e.pageX < that.X + (that.W / 2)) && (e.pageY > that.Y - (that.H / 2) && e.pageY < that.Y + (that.H / 2))) {
        if (that.isNotTransparent(e)) {
            that.onClick();
        }
    }
}
下面的一切就是把上面的东西发射出去

var items = new Array();

var afb = new Afbeelding();
afb.draw();
afb.onClick = function () {
    alert('clicked');
}
items.push(afb);


document.addEventListener('mousedown', function (e) {
    items.forEach(function (item, index) {
        item.clicked(e);
    });
});

事实上,但这似乎是他想要的。我知道我需要先画一个圆,我以后会在我的代码中这样做,但是如果我在上下文中有一个背景矩形,当我单击圆旁边时,它将得到背景矩形的图像数据,当我想返回alpha rgba的0值时。所以你必须检查鼠标是否指针正好在圆内(指针到圆心的距离<圆半径)。您必须在数组中存储这些圆的坐标和大小,并每次针对该数组测试鼠标指针x/y,因为这些对象不作为单独的实体存在,在绘制到画布上下文后可以查询/操作它们。不过,这不是我想要的,如果(情况就是这样)我在画布上放置了一个png图像。计算该形状有点困难。你的意思是要在保存画布中放置多个上下文吗?getImageData似乎忽略了这一点,如果我请求ctx上下文的imagedata,但没有绘制任何内容,它仍然会进入我的背景上下文(其他getContext('2d'))返回数据。不,我的意思是你必须有单独的画布对象,每个对象都有自己的上下文,并且你必须用CSS或JS将它们相互层叠。当我在我的页面上放置大约200个画布时,这将需要很多浏览器。我会去看看是否能找到对我的项目更有用的东西。但是谢谢,我现在知道了这不可能是我想要的方式。很抱歉,这不是您想要的答案,但是对于这么多的项目,我强烈建议您总体上看Raphael或SVG。无论如何,矢量图形往往重量较轻,但如果您要导入大量这样的PNG,我想您最终会遇到问题。有几个l Canvas和SVG都有很好的库。祝你好运,如果你找到了一个解决方案,把它贴在这里,让其他人也可以学习!谢谢你关于Raphael的提示,这是一个很好的建议!我明天会深入研究它!真的很好奇,这个规模有多大?OP提到必须在他的画布上添加200个PNG,你会推荐任何方法吗g如此高效,或者200应该很容易完成