【问题标题】:Grab from one HTML5 canvas and draw to another从一个 HTML5 画布中抓取并绘制到另一个
【发布时间】:2013-01-18 21:28:35
【问题描述】:

我正在尝试从一个画布元素中获取像素信息,对其进行操作,然后将其绘制到另一个画布元素中。当我在同一个画布上画画时,我已经能够完成这项工作。它也可以按特定顺序工作,但不是我需要的顺序。

这个想法是让隐藏的画布保存图像信息,我可以从中提取像素,进行操作,然后绘制到主画布。这在我从 myCanvas 绘制到 myCanvas2 时有效,但反之则不行。我从中获取数据的图像不需要是画布,事实上,我希望它不是我想要的尽可能少的资源。

<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

<canvas id="myCanvas2" width="800" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

<script>
var image = new Image();
image.src = 'http://timsterrible.net/gaming/pixelsweeper/images/bariumStrip.png';

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(10,10,50,50);

var canRaw = document.getElementById("myCanvas2");
var canvas = canRaw.getContext("2d");

image.onload = canvas.drawImage(image, 0, 0);

function copy()
{
var imgData=ctx.getImageData(32,0,32,32);
canvas.putImageData(imgData,10,70);
}
</script>

<button onclick="copy()">Copy</button>

</body>
</html>

我的目标是在混合时将一种化学品泄漏到另一种化学品中。现在它们非常坚固,您可以通过play around here 看到。

感谢您为解决这个令人困惑的烦恼提供的任何帮助。

http://timsterrible.net/gaming/pixelsweeper/stack/notmixing.png

【问题讨论】:

  • 那么您的问题到底是什么?您在寻找globalCompositeOperation 还是globalAlpha
  • globalAlpha 和 globalCompositeOperation 都是非常有用的工具。但是,我必须手动进行图像数据处理,因为这两种工具都不会从一个图像渐变到另一个图像。幸运的是,这不是问题。我遇到的问题,最终的问题是;为什么我可以从一个画布收集图像数据,而不能从另一个画布收集?
  • 检查这个答案可能有用[stackoverflow][1] [1]:stackoverflow.com/questions/13873374/…

标签: javascript image-processing html5-canvas


【解决方案1】:

希望以下内容可以为您解决问题提供一些帮助。 将函数 getPixel 作为一种方法添加到用于包含从中提取数据所需的图像的画布中。 将函数 putPixel 作为方法添加到用于包含最终组合图像的画布中。

我添加了函数的快速测试,以查看summer.jpgwinter.jpg 两个图像的中心部分是否正确组合。

以下代码的限制是画布和图像都具有相同的宽度和高度,但可以轻松更改。

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>pixel swap</title>
<style type="text/css">
    div, canvas, img {
        position: absolute;
    }

    img {
        top:0px;
        left:0px;
        visibility:hidden;
    }

    #imagedata {
        left:10px;
        top:10px;
        visibility:hidden;
    }
    #maincanvas {
        left:10px;
        top:10px;
        border:1px solid black;
    }

</style>
<script type="text/javascript">
    // abbreviation function for getElementById
    function $(id) {
      return document.getElementById(id);
    }

    //height and width for all canvases and images
    var W=100;
    var H=100;

    //variables for canvases
    var cid, cmain;


    /*getPixel gets an individual pixel from the image, img
     */
    function getPixel(x,y,img) {
        this.ctx.drawImage(img,0,0);
        var imdata=this.ctx.getImageData(0,0,this.width,this.height);
        var col=4*(y*this.width+x);
        var pix=new Pixel();
        pix.red=imdata.data[col++];
        pix.green=imdata.data[col++];
        pix.blue=imdata.data[col++];
        pix.alpha=imdata.data[col];
        return pix;
    }

    //Pixel Object
    function Pixel() {
        this.red;
        this.green;
        this.blue;
        this.alpha;
    }

    function putPixel(x,y,pixel){
        var imdata=this.ctx.getImageData(0,0,this.width,this.height);
        var col=4*(y*this.width+x);
        imdata.data[col++]=pixel.red;
        imdata.data[col++]=pixel.green;
        imdata.data[col++]=pixel.blue;
        imdata.data[col]=pixel.alpha;
        this.ctx.putImageData(imdata,0,0);
    }


    function main() {
        //set cid so that pixels are readable
        cid=$("imagedata");
        cid.width=W;
        cid.height=H;
        cid.ctx=cid.getContext('2d');
        cid.getPixel=getPixel;

        //set cmain so that pixels are settable to main canvas
        cmain=$("maincanvas");
        cmain.width=W;
        cmain.height=H;
        cmain.ctx=cmain.getContext('2d');
        cmain.putPixel=putPixel;

        var img; //image read from
        var pixel;//pixel data

        //testing getPixel and putPixel
        //should be alternating columns in the centre of the combined image in cmain canvas
        for(var x=30;x<70;x++) {
            for(var y=30;y<70;y++) {
                if(x%2==0) {
                    img=$("s")
                }
                else
                {
                    img=$("w")
                }
                pixel=cid.getPixel(x,y,img);
                cmain.putPixel(x,y,pixel);
            }
        }
    }
</script>
</head>
<body onload="main()">
    <!-- list of hidden images for reading data-->
    <img id="s" src="images/summer.jpg">
    <img id="w" src="images/winter.jpg">
    <!-- end of list of images  -->

    <canvas id="imagedata"></canvas>
    <canvas id="maincanvas"></canvas>   
</body>
</html>

【讨论】:

  • 恐怕我的代码有问题。我尝试了几种变体,使用了控制台日志等。结论是我的计算机绝对讨厌 getImageData 函数。我将尝试一些解决方法,包括将要操作的图像保存为 32 位位图,并将其数值保存到文本文档中。然后,我会在脚本开始时逐个像素地创建图像数据,并将数据存储在一个随时可用的数组中。
  • 显然有security issues surround getimagedata。上面的代码在我的本地计算机上似乎可以正常工作,前提是图像如所述。如果我将 src 替换为指向其在网络上的 url 参考的链接,它将不再有效。您是下载图片还是直接链接到它们?
  • 我看到它们是下载的,所以我决定我不妨在 MS Paint 中快速制作自己的涂鸦,然后在本地运行代码。我在我妻子的笔记本电脑上运行了同样的代码,效果很好。这告诉我,就像其他任何事情一样,并非所有计算机都能做所有事情。我将图像转换为位图并提取要从文本文件中读取的像素数据。效果很好。
  • 我尝试再次运行该程序,现在它可以工作了!事实证明,我错过了有关保存在硬盘驱动器上的安全标记文件的全部内容。当我在我妻子的电脑上进行测试时,它是在线的,这就是它起作用的原因。使用隐藏的画布来保存图像比我使用文本文件的解决方法要好得多。
猜你喜欢
  • 2015-08-12
  • 1970-01-01
  • 2011-06-03
  • 2012-07-12
  • 2012-11-27
  • 2011-12-10
  • 1970-01-01
  • 2020-05-17
  • 1970-01-01
相关资源
最近更新 更多