Aflred
Aflred

Reputation: 4603

ImageData flip image javascript

How can i rotate a image 45 degrees contained in an ImageData object?

https://developer.mozilla.org/en/docs/Web/API/ImageData

I do not want to do that with canvas i just want for ImageData.

Upvotes: 0

Views: 1867

Answers (1)

Blindman67
Blindman67

Reputation: 54128

Scan line rendering.

Why in imageData?? it is very slow

You can use a scan line renderer. This scans across the new (destination) row by row, calculating the x,y coordinate of the pixel at that point and then setting the color to match.

The example rotates the image via the image data array. the Rotation amount and the rotation center are set and a very simple matrix (ax,ay,ox,oy) is created to rotate a scan pixel (x,y) into a lookup pixel (rx,ry). The solution is a nearest neighbour lookup, but you can create a bilinear, or tri etc by interpreting the pixel colors via the fractional remainder of the rx,ry pixel locations.

const ctx = canvas.getContext("2d");
const randI = (min, max = min + (min = 0)) => (Math.random() * (max - min) + min) | 0;
const doFor = (count, cb) => { var i = 0; while (i < count && cb(i++) !== true); }; 


doFor(150,i=>{
  ctx.fillStyle = "hsl("+randI(360)+",100%,50%)";
  ctx.fillRect(randI(canvas.width),randI(canvas.height),randI(10,20),randI(10,20));
});
ctx.font = "28px Arial black";
ctx.textAlign = "center";
ctx.fillStyle = "black";
ctx.strokeStyle = "white";
ctx.lineWidth = "5";
ctx.lineJoin = "round";
ctx.strokeText("Rotate me!",128,128);
ctx.fillText("Rotate me!",128,128);


// the rotation origin    
const ox = 128;
const oy = 128;
// the rotation amount
const rot = Math.PI / 4; // 45 deg
// the rotated x axis
const ax = Math.cos(rot); // 45 deg
const ay = Math.sin(rot); // 45 deg
// get the source pixel data
const imageData = ctx.getImageData(0,0,256,256);
const d32 = new Uint32Array(imageData.data.buffer);
// create a destination pixel array
const rotImageData = new Uint32Array(imageData.data.length/4);
// scan each pixel and row adding pixels to rotImageData from the transformed
// x,y coordinate.
for(y = 0; y < 256; y += 1){
  for(x = 0; x < 256; x += 1){
    const ind = (x + y * 256);
    // transform the current pixel to the rotated pixel
    const rx = (x - ox) * ax - (y-oy) * ay + ox;
    const ry = (x - ox) * ay + (y-oy) * ax + oy;
    // use nearest pixel lookup and get index of original image
    const ind1 = ((rx | 0) + (ry | 0) * 256);
    rotImageData[ind] = d32[ind1];
  }
}
// create a second canvas
var c1 = document.createElement("canvas");
c1.width = 256;
c1.height = 256;

var ctx1 = c1.getContext("2d"); 
// put the new image data into the imageData array
d32.set(rotImageData);
// and put that on the new canvas
ctx1.putImageData(imageData,0,0);
// add the canvas to the page
document.body.appendChild(c1);


    
    
  
canvas {border : 2px solid black;}
<canvas id="canvas" width=256 height=256></canvas>

Upvotes: 2

Related Questions