image-rs / image-gif

GIF en- and decoder
Apache License 2.0
150 stars 40 forks source link

Add option to control pallete size #192

Open nathaniel-daniel opened 5 months ago

nathaniel-daniel commented 5 months ago

While creating a frame in the process of encoding, this library is able to quantize the colors in an rgba buffer to a pallete of 256 colors. I'm interested in reducing this pallete size to reduce the size of the produced gif. In short, I would like to extend this method on Frame:

pub fn from_rgba_speed
    width: u16
    height: u16
    pixels: &mut [u8],
    speed: i32,
) -> Frame<'static>

to something like this:

pub fn from_rgba_speed
    width: u16
    height: u16
    pixels: &mut [u8],
    speed: i32,
    pallete_size: u8
) -> Frame<'static>

Alternatively, I could implement the relevant functionality myself and pass the indexed pixels and pallete to the appropriate constructor, but I think it would be nice to expose an option to tune the pallete size since the library already seems to do the work for me.

kornelski commented 5 months ago

I don't think it'd be of much help:

  1. The neuquant algorithm these functions use is poorly suited for lower numbers of colors (it assumes all the colors form a smooth gradient, and lower numbers of colors have discontinuities it doesn't handle).

  2. Reducing the number of colors by half only reduces LZW symbol sizes by 1/9th. Lowering number of colors usually adds more dithering noise, which also counteracts the savings from fewer colors.