Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

greyscale().raw() sets wrong OutputInfo.channels #1425

Closed
hallsbyra opened this issue Oct 23, 2018 · 5 comments
Closed

greyscale().raw() sets wrong OutputInfo.channels #1425

hallsbyra opened this issue Oct 23, 2018 · 5 comments

Comments

@hallsbyra
Copy link

After doing a grayscale() operation, OutputInfo.channels = 3, when it really should be 1.

Example:

const logo = await logoSrc
    .greyscale()
    .raw()
    .toBuffer({ resolveWithObject: true })
// This is set to 3, which is wrong. It should be 1 since the picture is grayscale. Have to manually adjust it to 1.
logo.info.channels = 1
@lovell
Copy link
Owner

lovell commented Oct 23, 2018

Hello, did you see the greyscale docs?

"By default the output image will be web-friendly sRGB and contain three (identical) color channels. This may be overridden by other sharp operations such as toColourspace('b-w'), which will produce an output image containing one color channel."

@hallsbyra
Copy link
Author

Yes, but I'm not sure it's correct. Look at this:

const gray = await sharp({create: {width: 100, height: 100, channels: 3, background: {r: 255, g: 255, b: 255}}})
    .greyscale()
    .raw()
    .toBuffer({resolveWithObject: true})
// Comment out this line to get: VipsImage: memory area too small --- should be 30000 bytes, you passed 10000
gray.info.channels = 1
const out = await sharp(gray.data, {raw: {width: gray.info.width, height: gray.info.height, channels: gray.info.channels}})
    .raw()
    .toBuffer()

After the first operation, gray.info.channels = 3. Ok. As per the docs. Problem is, gray.data.length = 10000. And that's just one channel (100x100), or what am I getting wrong? Forcing it to one channel makes the second operaton work.

@lovell
Copy link
Owner

lovell commented Oct 23, 2018

Yes, sorry, using raw output extracts a single channel when greyscale is also used so this is a bug.

Happy to accept and/or help with a PR if you're able to add the fix and a test case. baton->channels needs to be modified inside the if block approximately here:

sharp/src/pipeline.cc

Lines 771 to 774 in de11d36

if (baton->greyscale || image.interpretation() == VIPS_INTERPRETATION_B_W) {
// Extract first band for greyscale image
image = image[0];
}

@lovell lovell added bug and removed question labels Oct 23, 2018
@lovell lovell changed the title greyscale() sets wrong OutputInfo.channels greyscale().raw() sets wrong OutputInfo.channels Oct 23, 2018
@lovell lovell added this to the v0.21.1 milestone Nov 19, 2018
@lovell
Copy link
Owner

lovell commented Nov 19, 2018

Commit 6f9699f adds a test assertion that would have caught this, plus fixes the bug. This will be in v0.21.1, thanks for reporting.

@lovell
Copy link
Owner

lovell commented Dec 7, 2018

v0.21.1 is now available with this fix.

@lovell lovell closed this as completed Dec 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants