PutImageData (), how to save old pixels if new pixels are transparent?

In html5, when you draw to the canvas using putImageData (), if some of the pixels you draw are transparent (or translucent), how can you not change the old pixels in the canvas?

Example:

var imgData = context.createImageData(30,30);
for(var i=0; i<imgData.data.length; i+=4)
{
imgData.data[i]=255;
imgData.data[i+1]=0;
imgData.data[i+2]=0;
imgData.data[i+3]=255;
if((i/4)%30 > 15)imgData.data[i+3] = 0;
}
context.putImageData(imgData,0,0);

The right half of the 30x30 rectangle is transparent. If it is painted over something on the canvas, the pixels behind the right half are deleted (or become transparent). How to save them?

+4
source share
3 answers

You can use getImageData to create a translucent overlay:

  • create temporary screen
  • getImageData to get pixel data from a splash canvas
  • .
  • putImageData
  • drawImage .

enter image description here

: http://jsfiddle.net/m1erickson/CM7uY/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

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

    // draw an image on the canvas
    var img=new Image();
    img.onload=start;
    img.src="https://dl.dropboxusercontent.com/u/139992952/stack1/landscape1.jpg";
    function start(){
        canvas.width=img.width;
        canvas.height=img.height;
        context.drawImage(img,0,0);

        // overlay a red gradient 
        drawSemiTransparentOverlay(canvas.width/2,canvas.height)

    }

    function drawSemiTransparentOverlay(w,h){

        // create a temporary canvas to hold the gradient overlay
        var canvas2=document.createElement("canvas");
        canvas2.width=w;
        canvas2.height=h
        var ctx2=canvas2.getContext("2d");

        // make gradient using ImageData
        var imgData = ctx2.getImageData(0,0,w,h);
        var data=imgData.data;
        for(var y=0; y<h; y++) {
            for(var x=0; x<w; x++) {
                var n=((w*y)+x)*4;
                data[n]=255;
                data[n+1]=0;
                data[n+2]=0;
                data[n+3]=255;
                if(x>w/2){
                    data[n+3]=255*(1-((x-w/2)/(w/2)));
                }
            }
        }

        // put the modified pixels on the temporary canvas
        ctx2.putImageData(imgData,0,0);

        // draw the temporary gradient canvas on the visible canvas
        context.drawImage(canvas2,0,0);

    }


}); // end $(function(){});
</script>
</head>
<body>
    <canvas id="canvas" width=200 height=200></canvas>
</body>
</html>

, , , .

http://jsfiddle.net/m1erickson/j6wLR/

+5

,

if((i/4)%30 > 15)imgData.data[i+3] = 0;

, . - context.putImageData, . , , putImageData - , .

createImageData, , getImageData, . , , . .

var imgData = context.getImageData(30,30);
for(var i=0; i<imgData.data.length; i+=4)
{
  if((i/4)%30 > 15) continue;
  imgData.data[i]=255;
  imgData.data[i+1]=0;
  imgData.data[i+2]=0;
  imgData.data[i+3]=255;
}
context.putImageData(imgData,0,0);
+2

CRISP, . , .

https://jsfiddle.net/4Le454ak/1/

:

var imageData = canvas.toDataURL(0, 0, w, h);
var tmp = document.createElement('img');
tmp.style.display = 'none'
tmp.src = imageData;
document.body.appendChild(tmp);
ctx.drawImage(tmp, 30, 30);

:

  • ( dom, )
  • you can remove or reuse at this point
0
source

Source: https://habr.com/ru/post/1530214/


All Articles