Description
I am trying to do some manual pixel level manipulations/extraction to a custom binary format.
Near the end of my manipulations, I use image.scan() to iterate through the pixels, following this example from the docs:
image.scan(0, 0, image.bitmap.width, image.bitmap.height, function(x, y, idx) {
// x, y is the position of this pixel on the image
// idx is the position start position of this rgba tuple in the bitmap Buffer
// this is the image
var red = this.bitmap.data[idx + 0];
var green = this.bitmap.data[idx + 1];
var blue = this.bitmap.data[idx + 2];
var alpha = this.bitmap.data[idx + 3];
// rgba values run from 0 - 255
// e.g. this.bitmap.data[idx] = 0; // removes red from this pixel
});
I've got this part working as I want (mostly).
Now I'm trying to do some manipulations to the image before my final output (monochrome, contain, etc). Those are working.
But as part of my development, I'd like to see the image in conventional viewers. So I added an image.write('modified') to my chain. Playing with various output formats, I noticed that it changed my final output generated from the image.scan(...).
Inspecting further, it looks like the order of the rgba has changed in the internal buffer and I think I traced this down to getBuffer() modifying the internal buffer to match the output file format.
Expected Behavior
Calling a image.getX() function should not modify subsequent calls on the image. Alternatively, there should be a consistent way to get the raw rgba values of each pixel in an image.
Current Behavior
Depending on the internal buffer state, a different rgba mapping must be used.
Steps to Reproduce
const image = await Jimp.read('test.png');
const orig = Buffer.from(image.bitmap.data);
image.write('test.bmp');
image.scan(0, 0, image.bitmap.width, image.bitmap.height, function(x, y, idx) {
// x, y is the position of this pixel on the image
// idx is the position start position of this rgba tuple in the bitmap Buffer
// this is the image
var red = this.bitmap.data[idx + 0];
var green = this.bitmap.data[idx + 1];
var blue = this.bitmap.data[idx + 2];
var alpha = this.bitmap.data[idx + 3];
var redOrig = orig[idx + 0];
var greenOrig = orig[idx + 1];
var blueOrig = orig[idx + 2];
var alphaOrig = orig[idx + 3];
if (
red != redOrig ||
green != greenOrig ||
blue != blueOrig ||
alpha != alphaOrig
) throw new Error('Colors changed!');
});
Possibly related
It looks like this might have been a change introduced by #530, trying to fix #521.