mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-14 08:56:08 +00:00
Edit Colors: convert embedded images to indexed color
Edit > Edit Colors > Convert to Indexed Color... (edit.colors.toIndexed) stores the embedded images in the selection as indexed-color PNGs: a palette of at most 256 RGB colors, each pixel the index of one. The dialog previews live and OK is one undo step. - The palette is chosen as for a PNG-8 export (selective, perceptual, adaptive, web, gray, black and white), as evenly spaced levels of red, green and blue (uniform), or from the document's swatches. Dithering is diffusion, pattern, noise or none, with an amount. - Pixels under half opacity become one transparent entry; the others become opaque in their own color. Linked images, colorized images and color glyph images keep their pixels. - An image that is already an indexed PNG and would show the same pixels is left as it is, and no undo step is recorded when no image changes. - An image of more than 134,217,728 pixels (33,554,432 in the web app) is refused, read from its header before decoding. - With Select All, locked and hidden objects that hold an image that is not an indexed PNG yet are counted in notChanged, without converting them. - The quantizer gains quantize_to, which maps pixels to a given palette. Docs: docs/mcp.md, docs/target-app-parity.md.
This commit is contained in:
@@ -194,6 +194,27 @@ impl ImageBlob {
|
||||
.collect();
|
||||
Some((w, h, cover))
|
||||
}
|
||||
|
||||
/// The pixels as straight RGBA, row by row from the top, with the width and the height;
|
||||
/// `None` when the image can't be decoded within [`MAX_RASTER_ALLOC`].
|
||||
pub fn rgba(&self) -> Option<(u32, u32, Vec<u8>)> {
|
||||
let img = rgba_within(&self.bytes, MAX_RASTER_ALLOC)?;
|
||||
let (w, h) = img.dimensions();
|
||||
Some((w, h, img.into_raw()))
|
||||
}
|
||||
|
||||
/// The width and height in pixels the image's file says it has; `None` for data that isn't an
|
||||
/// image the decoder reads. Reads only its header.
|
||||
pub fn pixel_size(&self) -> Option<(u32, u32)> {
|
||||
image::ImageReader::new(Cursor::new(self.bytes.as_slice())).with_guessed_format().ok()?.into_dimensions().ok()
|
||||
}
|
||||
|
||||
/// Whether the image's file is a PNG that stores palette indices (an indexed-color image).
|
||||
/// Reads only its header.
|
||||
pub fn indexed_png(&self) -> bool {
|
||||
// The signature, then the IHDR chunk: length, type, width, height, bit depth, color type.
|
||||
self.bytes.starts_with(b"\x89PNG\r\n\x1a\n") && self.bytes.get(12..16) == Some(b"IHDR".as_slice()) && self.bytes.get(25) == Some(&3)
|
||||
}
|
||||
}
|
||||
|
||||
impl ImageBlob {
|
||||
|
||||
Reference in New Issue
Block a user