【问题标题】:Canvas image flattern - combine imageData画布图像展平 - 结合 imageData
【发布时间】:2015-01-23 11:09:22
【问题描述】:

您好,我已经实现了一个函数,在该函数中我传递了一个包含透明部分的 png 图像 (rgba) 的 imageData 数组。我使用下面的代码将图像展平,但我有一个关于 alpha 的问题,我可以使用一些帮助。正如您在下面的屏幕截图中看到的那样,红色文本有一个半透明的黑色阴影,而是呈现为白色而不是半透明。

var mergeImageData = function ( imageDataArray ) {

    var canvas = document.getElementById( 'canvas' );
    canvas.width = 512;
    canvas.height = 512;
    var ctx = canvas.getContext( '2d' );
    var newImageData = imageDataArray[ 0 ];


    for ( var j = 1, len = imageDataArray.length; j < len; j++ ) { // iterate through the imageDataArray

        console.log( imageDataArray[ j ].data.length );

        for ( var i = 0, bytes = imageDataArray[ j ].data.length; i < bytes; i += 4 ) { // iterate through image bytes

            var index = ( imageDataArray[ j ].data[ i + 3 ] === 0 ? 0 : j );

            newImageData.data[ i ] = imageDataArray[ index ].data[ i ];
            newImageData.data[ i + 1 ] = imageDataArray[ index ].data[ i + 1 ];
            newImageData.data[ i + 2 ] = imageDataArray[ index ].data[ i + 2 ];
            newImageData.data[ i + 3 ] = imageDataArray[ index ].data[ i + 3 ];
        }

    }

    ctx.putImageData( newImageData, 0, 0 );
    console.log( "all done" );

};

重要 这将在未来在webworker 中完成,这就是我对这种方法感兴趣的原因,因为网络工作者没有画布访问权限。

【问题讨论】:

  • 只是猜测-这一行:newImageData.data[ i + 3 ] = imageDataArray[ index ].data[ i + 3 ];只是将透明度设置为当前 PNG,不应该只是将其设置为 1 吗?
  • 值在 0 到 255 之间,如果我将其设置为 1,则展平图像不可见
  • 至少你没有得到白色轮廓:-)
  • 是因为putImageData()不注意合成,只读取像素。您需要在内存中的画布中 putImageData(),然后将 drawImage() 这个画布添加到您实际渲染的画布中。
  • 您想将纹理混合在一起。你更喜欢多线程而不是硬件加速。很有趣。

标签: javascript canvas web-worker


【解决方案1】:

您的第一个问题是putImageData() 功能:根据this answer @ellisbben

putImageData 方法不关注合成;它只是复制像素值。为了进行合成,我们需要使用绘图操作。

因此,您必须在内存中使用第二个画布(在 this answer 中由 @markE 描述)。

然后,您的第二个问题是您想在 webworker 中执行此操作。
你是对的,网络工作者似乎无法处理这样的绘图操作:根据this answer@AshleysBrain

Web Worker 只能计算,不能修改 DOM 或进行任何调用以绘制到画布。

因此,您唯一的方法是通过工作人员处理数据来拆分您的操作,然后将其绘制到您的主线程中。

这是一个示例,假设您的根文件夹中有 2 个分别称为 test0.png 和 test1.png 的 png 文件。

index.html

<html>
  <body>
  <canvas id="canvas"></canvas>
  </body>
   <script src="main.js"></script>
</html>

ma​​in.js

if (!!window.Worker) {
    var myWorker = new Worker("worker.js");

    myWorker.onmessage = function(e) {
        var tmp=document.createElement("canvas");
        tmp.width=512;
        tmp.height=512;
        var ctx2=tmp.getContext("2d");
        ctx2.putImageData(e.data[0],0,0);

        var canvas = document.getElementById( 'canvas' );
        canvas.width = 512;
        canvas.height = 512;
        var ctx = canvas.getContext( '2d' );
        ctx.fillStyle = "rgb(0,255, 0)";
        ctx.fillRect(0,0,250,50);
        ctx.drawImage(tmp,0,0);
    }
}

  var images = [];
  function getImagesData(){
    for(i=0; i<2; i++){
        var img = new Image();
        img.src = "test"+i+".png";
        //Should add an onload method
        var canvas = document.createElement("canvas");
        canvas.width = img.width;
        canvas.height = img.height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);

        images[i] = ctx.getImageData(0,0,img.width,img.height);
        }
    myWorker.postMessage(images);
    }

getImagesData();

Worker.js

var mergeImageData = function( imageDataArray ) {

    var newImageData = imageDataArray[ 0 ];

    for ( var j = 0; j < imageDataArray.length; j++ ) { // iterate through the imageDataArray


        for ( var i = 0, bytes = imageDataArray[ j ].data.length; i < bytes; i += 4 ) { // iterate through image bytes

            var index = ( imageDataArray[ j ].data[ i + 3 ] === 0 ? 0 : j );

            newImageData.data[ i ] = imageDataArray[ index ].data[ i ];
            newImageData.data[ i + 1 ] = imageDataArray[ index ].data[ i + 1 ];
            newImageData.data[ i + 2 ] = imageDataArray[ index ].data[ i + 2 ];
            newImageData.data[ i + 3 ] = imageDataArray[ index ].data[ i + 3 ];
        }
    }
    return newImageData;
};


onmessage = function(e) {
var res = mergeImageData(e.data);
postMessage([res]);
}

原始 png 文件

结果

【讨论】:

    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-09
      • 1970-01-01
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 2020-10-24
      • 1970-01-01
      相关资源
      最近更新 更多