Reputation: 670
This is working, but I feel this code is lengthy. I'm looking for better idea.
var clone = function(imageData) {
var canvas, context;
canvas = document.createElement('canvas');
canvas.width = imageData.width;
canvas.height = imageData.height;
context = canvas.getContext('2d');
context.putImageData(imageData, 0, 0);
return context.getImageData(0, 0, imageData.width, imageData.height);
};
Upvotes: 16
Views: 7957
Reputation: 152
With TypedArray.prototype.set()
you can directly copy the data.
var imageDataCopy = new Uint8ClampedArray(originalImageData.data);
imageDataCopy.set(originalImageData.data);
This sets the content of imageDataCopy
to be identical to originalImageData
.
Upvotes: 12
Reputation: 21619
Most times it should be sufficient to simply assign the imageData
to a new variable, just like:
myImgData=ctx.getImageData(0,0,c.width,c.height); //get image data somewhere
imgDataCopy = myImgData; // clone myImgData
...now imgDataCopy
contains a separate copy of myImgData
. 🤷♂️
The snippet below creates 4 "frames" in an array of ImageData
's and then loop through them.
const c = document.getElementById('canvas'),
ctx = c.getContext("2d");
var wh=70, iDatas=[], i=0,
lines=[[10,10,wh-10,wh-10], [wh/2,5,wh/2,wh-5], // ⤡,↕
[wh-10,10,10,wh-10], [5,wh/2,wh-5,wh/2]]; // ⤢,↔
c.width=wh;
c.height=wh;
ctx.strokeStyle='blue'; //setup to draw
ctx.lineWidth=9;
ctx.lineWidth='round';
for(var [x1,y1,x2,y2] of lines){
ctx.beginPath();
ctx.moveTo(x1,y1); //draw something
ctx.lineTo(x2,y2);
ctx.stroke();
var d=ctx.getImageData(0,0,c.width,c.height); //get imgdata
iDatas.push( d ); //save imgdata to array
ctx.clearRect(0, 0, c.width, c.height); //clear canvas
}
ctx.strokeStyle='green'; //❌has no effect:
// ↑ shows that color data comes from the source (can't be changed)
ctx.lineWidth='round'; //❌has no effect:
// ↑ shows that non-color styling does NOT come from source (CAN'T be changed)
//now you can refer to the image data as iData[i] where i= 0 to 3
drawFrame();
function drawFrame(){
ctx.putImageData( iDatas[i],0,0); //draw imgData from array
i=(i==3?0:i+1); //set next iteration #
setTimeout(function(){ drawFrame() }, 100); //schedule next frame
}
canvas{ border:2px dotted salmon; }
<canvas id='canvas'></canvas>
Upvotes: -4
Reputation: 413
The ImageData constructor accepts the image data array.
const imageDataCopy = new ImageData(
new Uint8ClampedArray(imageData.data),
imageData.width,
imageData.height
)
Upvotes: 19