镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Enhancement: Investigate control over output PNG IDAT chunk size, might reduce file size of smaller palette-based images #4489

Open

Description

@guoyunhe

Question about an existing feature

What are you trying to achieve?

I have some PNG images. I want to use sharp to compress them and reduce file sizes.

I tried a few options. However, the output size (13.3KB) is always bigger than input size (11.4KB).

When you searched for similar issues, what did you find that might be related?

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this question

https://github.com/retrobrainz/image-compress-test

Please provide sample image(s) that help explain this question

See the repo above

Activity

  1. changed the title [-]PNG compression result is bigger than input[/-] [+]PNG output is bigger than PNG input[/+] on Jan 16, 2026
  2. lovell commented on Jan 16, 2026

    @lovell
    Owner

    It looks like input.png is a palette-based PNG with a meaning-of-lifesque 42 colours:

    $ pngchunks input.png | grep PLTE
    Chunk: Data Length 126 (max 2147483647), Type 1163152464 [PLTE]
    

    (3 channels * 42 colours = 126 bytes)

    You can reduce the number of colours in the palette with colours, for example:

      .png({
        palette: true
        effort: 10,
    +   colours: 64,
      })
  3. guoyunhe commented on Jan 17, 2026

    @guoyunhe
    Author

    I added colors: 64 and the result:

    1. output.png (12.8KB) is still bigger than input.png (11.4KB)
    2. Image quality is downgraded. Some colors are visually different.

    https://github.com/retrobrainz/image-compress-test

  4. lovell commented on Jan 18, 2026

    @lovell
    Owner

    It looks like the input image was optimised using a tool such as pngcrush. Even with compressionLevel set to its highest value I see the following difference:

    $ pngchunks input.png | grep IDAT
    Chunk: Data Length 11482 (max 2147483647), Type 1413563465 [IDAT]
    
    $ pngchunks output.png | grep IDAT
    Chunk: Data Length 8192 (max 2147483647), Type 1413563465 [IDAT]
    Chunk: Data Length 4911 (max 2147483647), Type 1413563465 [IDAT]
    

    We previously investigated setting the max IDAT/buffer size in libvips but found the savings were not very useful, however this specific image might be the case that proves otherwise - see libvips/libvips#1357

  5. guoyunhe commented on Jan 18, 2026

    @guoyunhe
    Author

    This image (screenshot) was generated by https://github.com/libretro/retroarch (Hope it is helpful)

  6. lovell commented on Jan 18, 2026

    @lovell
    Owner

    Thanks, it appears to write a single IDAT chunk (similar to pngcrush).

    https://github.com/libretro/RetroArch/blob/bd15d7c02d2614ae878cd2947ba0664269cf2ee0/libretro-common/formats/png/rpng_encode.c#L339-L341

    I'll mark this as a future possible enhancement for now.

  7. changed the title [-]PNG output is bigger than PNG input[/-] [+]Enhancement: Investigate control over output PNG IDAT chunk size, might reduce file size of smaller palette-based images[/+] on Jan 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions