Skip to content

Pixel type is not constructable. #1

@bddap

Description

@bddap

It's very nearly possible to serialize some image as sixel using this library. Just missing one thing.

To use the SixelSerializer type we need to pass in Pixels, but Pixels is has no constructor and its fields are private.

This sample code demonstrates what the sixel-image crate can almost do:

use std::collections::{BTreeMap, HashMap, HashSet};

use image::RgbaImage;
use itertools::Itertools;
use sixel_image::SixelColor;

fn render_sixel(img: &RgbaImage) -> String {
    let colors: HashMap<[u8; 3], u16> = img
        .pixels()
        .map(|p| [p[0], p[1], p[2]].map(compress))
        .collect::<HashSet<[u8; 3]>>() // dedup
        .into_iter()
        .enumerate()
        .map(|(i, c)| (c, wrapping_into(i)))
        .collect();
    let color_registers: BTreeMap<u16, SixelColor> = colors
        .iter()
        .map(|(&c, &i)| (i, SixelColor::Rgb(c[0], c[1], c[2])))
        .collect();

    let pixels: Vec<Vec<sixel_image::Pixel>> = img
        .pixels()
        .map(|p| {
            let c = [p[0], p[1], p[2]].map(compress);
            let ci = colors[&c];
            unimplemented!("can't construct the `Pixel` from external crate")
        })
        .chunks(img.width() as usize)
        .into_iter()
        .map(|c| c.collect())
        .collect();

    sixel_image::SixelSerializer::new(&color_registers, &pixels).serialize()
}

fn wrapping_into(u: usize) -> u16 {
    (u % u16::MAX as usize) as u16
}

/// compress a color value from the range [0, 255] to the range [0, 100]
fn compress(a: u8) -> u8 {
    (a as u16 * 100 / 255) as u8
}

fn main() {
    let img = image::RgbaImage::new(100, 100);
    println!("{}", render_sixel(&img));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions