0

I have data from 2d image in a 1D array, plot is perfect but I would like to reverse y axis. I saw tips with ctx.transform but it doesn't seems to work on this example:

https://jsfiddle.net/92j9r2j4/2/

Z array just for example, Z[n*n-1] is used to mark the corner.

froggy
  • 513
  • 2
  • 6
  • 21

1 Answers1

2

ctx.putImageData is not affected by transform.

The image data functions getImageData and putImageData are not affected by the current transform. They are memory blit (move) functions not graphical functions.

You have several options.

Flip rendered content

In this case you create the data as normal but after you copy the content to the canvas you draw the canvas over itself with the transform ctx.setTransform(1,0,0,-1,0,n - 1). If you had transparent pixels you would need to use the composite mode "copy" to replace pixels rather than blend them.

var i,j;
const n = 200;
const size = n ** 2;  // ** is to power of
//const canvas = document.querySelector('canvas'); // not needed canvas is 
                                                   // already defined with 
                                                   // id="canvas"
const ctx = canvas.getContext("2d");
const imgData = ctx.createImageData(n, n);
const Z = [];
for (j = 0; j < size; j ++) { Z[j] = j * 256 / size }
Z[n * n - 1] = 0;
i = 0;
for (j = 0; j < size; j++) {
  imgData.data[i++] = Z[j];
  imgData.data[i++] = Z[j];
  imgData.data[i++] = Z[j];
  imgData.data[i++] = 255;
}
ctx.putImageData(imgData, 0, 0);

// flip the canvas
ctx.transform(1, 0, 0, -1, 0, canvas.height)
ctx.globalCompositeOperation = "copy"; // if you have transparent pixels
ctx.drawImage(ctx.canvas,0,0);
ctx.globalCompositeOperation = "source-over"; // reset to default
<canvas id="canvas" width=200 height=200></canvas>

Flip data copy

In this case you flip the data as you copy it from the array to the image data array by calculating the flipped index for each pixel.

var i,j;
const n = 200;
const size = n ** 2;  // ** is to power of
const ctx = canvas.getContext("2d");
const imgData = ctx.createImageData(n, n);
const Z = [];
for (j = 0; j < size; j++) { Z[j] = j * 256 / size }
Z[size - 1] = 0;
var i = 0;
for (j = 0; j < size; j++) {
  // get the index mirrored pixel
  i = (((n - 1) - ((j / n) | 0)) * n + (j % n)) * 4;
  imgData.data[i++] = Z[j];
  imgData.data[i++] = Z[j];
  imgData.data[i++] = Z[j];
  imgData.data[i++] = 255;
}
ctx.putImageData(imgData, 0, 0);
<canvas id="canvas" width=200 height=200></canvas>

Flip data creation

In this example you create the data flipped.

Not this example the data is flipped in x and y. The registration mark remains the same.

var i,j;
const n = 200;
const size = n ** 2;  // ** is to power of
const ctx = canvas.getContext("2d");
const imgData = ctx.createImageData(n, n);
const Z = new Uint8Array(n*n); // use an 8 bit array as a standard array will
                               // will be marked as sparse (slow) if you add
                               // out of order
for (j = 0; j < size ; j ++) {
    // reverse the order of values
    Z[size - 1 - j] = j * 256 / size; 
}
Z[n - 1] = 0;  // add black pixel at top right
i = 0;
for (j = 0; j < size; j ++) {
  imgData.data[i++] = Z[j];
  imgData.data[i++] = Z[j];
  imgData.data[i++] = Z[j];
  imgData.data[i++] = 255;
}
ctx.putImageData(imgData, 0, 0);
<canvas id="canvas" width=200 height=200></canvas>
Community
  • 1
  • 1
Blindman67
  • 51,134
  • 11
  • 73
  • 136
  • Yes flipping data what was i did . Ok for draw vs put thank you, and transparent pixel , this will be usefull too ! – froggy Nov 22 '17 at 10:38