rust-ico icon indicating copy to clipboard operation
rust-ico copied to clipboard

Indexed PNG palettes are not supported (workaround)

Open Ciantic opened this issue 1 year ago • 0 comments

I stumbled on this, as you know it's marked as not implemented, but I figured I can circumvent it with lodepng that supports indexed palettes.

Workaround

  1. Add
lodepng = { version = "3.10.0" }
  1. Use lodePNG to decode the PNG file to RGBA u8 vector:
    let decoded_png = lodepng::decode32(pngbytes.as_slice())?;
    let bytevector: Vec<u8> = decoded_png.buffer
        .iter()
        .flat_map(|pixel| [pixel.r, pixel.g, pixel.b, pixel.a])
        .collect();
    let icondata = ico::IconImage::from_rgba_data(
        decoded_png.width as u32,
        decoded_png.height as u32,
        bytevector,
    );
    
    // Then write to file normally with 

    let mut icon_dir = ico::IconDir::new(ico::ResourceType::Icon);
    icon_dir.add_entry(ico::IconDirEntry::encode(&icondata)?);
    icon_dir.write(std::fs::File::create(&icon_file)?)?;

Other thoughts

I would probably remove all support for reading PNG from this library and instead use just RGBA u8 vectors, this way you could have functions that take Vec<u8> (RGBA) and produce ICO files. If the user wants to have a paletted ICO file, then this library would take all distinct colors in Vec u8 and produce palettes, etc.

It would simplify the library and move the responsibility of loading PNG files to other libraries. I know, this has probably been just a little project which you are not actively maintaining, these are just my thoughts, no need to respond.

Overall I like the library nonetheless!

Ciantic avatar May 09 '24 11:05 Ciantic