Skip to content

getBuffer() modifies buffer (unexpectedly) #1050

@cinderblock

Description

@cinderblock

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugthere is a bug in the way jimp behaveshelp wanted

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions