jimp-dev / jimp-dev/jimp

getBuffer() modifies buffer (unexpectedly)

Open
#1,050 3 comments 0 reactions 0 assignees View on GitHub
bug help wanted
Dominant language
TypeScript
Stars
14.7k
Forks
777
PR merge metrics
No merged PRs in 30d

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:

```ts
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

```ts
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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.