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

How to use .png() to save a greyscale (1 channel), 1 bit image? #2834

Closed
amitm02 opened this issue Aug 9, 2021 · 8 comments
Closed

How to use .png() to save a greyscale (1 channel), 1 bit image? #2834

amitm02 opened this issue Aug 9, 2021 · 8 comments
Labels

Comments

@amitm02
Copy link

amitm02 commented Aug 9, 2021

I'm trying to use the .png() function to save:

  • An image to greyscale (1 channel), 1-bit png.
  • An image to greyscale (1 channel), 2-bit png.

I couldn't understand from the docs what should be the right "options" parameters.
appreciate any help.
awsome library BTW.

@lovell
Copy link
Owner

lovell commented Aug 11, 2021

Convert to greyscale and save as 1-bit palette PNG:

const png1 = await sharp(input)
  .greyscale()
  .png({ colours: 2 })
  .toBuffer()

Convert to greyscale and save as as 2-bit palette PNG:

const png2 = await sharp(input)
  .greyscale()
  .png({ colours: 4 })
  .toBuffer()

@amitm02
Copy link
Author

amitm02 commented Aug 12, 2021

am i to understand from link
By default, PNG output is full colour at 8 or 16 bits per pixel. Indexed PNG input at 1, 2 or 4 bits per pixel is converted to 8 bits per pixel.
That selecting .png({ colours: 2 }) will not really reduce the file size?

@lovell
Copy link
Owner

lovell commented Aug 12, 2021

Set palette to true for slower, indexed PNG output.

options.colours maximum number of palette entries, sets palette to true (optional, default 256)

When you provide a value for colours, you are changing from the default behaviour of full colour output to instead using indexed colour output, which usually reduces the file size.

@amitm02
Copy link
Author

amitm02 commented Aug 22, 2021

I get a smaller file with

{
            const optimizedBuffer = await sharp(buffer)
            .greyscale()
            .resize(595)
            .png({quality: 30})
            .toBuffer();
        }

than

 const optimizedBuffer = await sharp(buffer)
            .greyscale()
            .resize(595)
            .png({colors: 2})
            .toBuffer();  

if (assumingly) in PNG, quality just changes the palette,
How can it be? isn't 1bpp should give the smallest image size?

@lovell
Copy link
Owner

lovell commented Aug 22, 2021

Dropping the colours to 2 may increase the amount of dithering, which can increase entropy and reduce the LZW compression ratio. Dropping quality allows the quantisation to throw detail away. You'll need to experiment for a given input, perhaps also setting dither to zero.

@amitm02
Copy link
Author

amitm02 commented Aug 22, 2021

setting dither to zero had no effect on image size

@lovell
Copy link
Owner

lovell commented Aug 25, 2021

Is this issue superseded by #2855?

@lovell
Copy link
Owner

lovell commented Sep 5, 2021

I hope this information helped. I'll close as it looks like #2855 supersede this, but please feel free to re-open with more details if further assistance is required.

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

No branches or pull requests

2 participants