From 9d4ecaaf728135e761a34ece10535366f444a0e9 Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 15 Mar 2024 22:13:45 +0100 Subject: [PATCH] Print images lighter --- showbits-common/src/widgets/image.rs | 16 ++++++---------- showbits-thermal-printer/src/drawer.rs | 22 +++++++++++++++++++--- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/showbits-common/src/widgets/image.rs b/showbits-common/src/widgets/image.rs index 2a517c1..a3474ec 100644 --- a/showbits-common/src/widgets/image.rs +++ b/showbits-common/src/widgets/image.rs @@ -3,7 +3,7 @@ use image::{ RgbaImage, }; use mark::dither::{AlgoFloydSteinberg, AlgoStucki, Algorithm, DiffEuclid, Palette}; -use palette::{IntoColor, Srgb, Srgba}; +use palette::{IntoColor, LinSrgb, Srgba}; use taffy::prelude::{AvailableSpace, Layout, Size}; use crate::Widget; @@ -15,12 +15,12 @@ pub enum DitherAlgorithm { } impl DitherAlgorithm { - fn dither(self, image: RgbaImage, palette: &Palette) -> RgbaImage { + fn dither(self, image: RgbaImage, palette: &Palette) -> RgbaImage { match self { Self::FloydSteinberg => { - >::run(image, palette) + >::run(image, palette) } - Self::Stucki => >::run(image, palette), + Self::Stucki => >::run(image, palette), } } } @@ -31,11 +31,7 @@ pub struct Image { grow: bool, filter: FilterType, - // The palette uses Srgb instead of LinSrgb because dithering in Srgb - // produces better results when printed, even though color distance - // calculations are objectively wrong. Maybe the printer's black ink - // behaviour makes them correct again. - dither_palette: Option>, + dither_palette: Option>, dither_algorithm: DitherAlgorithm, } @@ -70,7 +66,7 @@ impl Image { let palette = palette .iter() .map(|c| c.color.into_color()) - .collect::>(); + .collect::>(); self.dither_palette = Some(Palette::new(palette)); self diff --git a/showbits-thermal-printer/src/drawer.rs b/showbits-thermal-printer/src/drawer.rs index 4c88c26..29b109f 100644 --- a/showbits-thermal-printer/src/drawer.rs +++ b/showbits-thermal-printer/src/drawer.rs @@ -1,6 +1,6 @@ mod calendar; -use image::RgbaImage; +use image::{Luma, Pixel, RgbaImage}; use showbits_common::{ color::{BLACK, WHITE}, widgets::{Block, FontStuff, HasFontStuff, Image, Text}, @@ -131,9 +131,17 @@ impl Drawer { Ok(()) } - fn on_image(&mut self, image: RgbaImage) -> anyhow::Result<()> { + fn on_image(&mut self, mut image: RgbaImage) -> anyhow::Result<()> { let mut tree = Tree::::new(WHITE); + for pixel in image.pixels_mut() { + let [l] = pixel.to_luma().0; + let l = l as f32 / 255.0; // Convert to [0, 1] + let l = 1.0 - (0.4 * (1.0 - l)); // Lerp to [0.6, 1] + let l = (l.clamp(0.0, 1.0) * 255.0) as u8; // Convert back to [0, 255] + *pixel = Luma([l]).to_rgba(); + } + let image = Image::new(image) .with_dither_palette(&[BLACK, WHITE]) .node() @@ -152,9 +160,17 @@ impl Drawer { Ok(()) } - fn on_photo(&mut self, image: RgbaImage, title: String) -> anyhow::Result<()> { + fn on_photo(&mut self, mut image: RgbaImage, title: String) -> anyhow::Result<()> { let mut tree = Tree::::new(WHITE); + for pixel in image.pixels_mut() { + let [l] = pixel.to_luma().0; + let l = l as f32 / 255.0; // Convert to [0, 1] + let l = 1.0 - (0.4 * (1.0 - l)); // Lerp to [0.6, 1] + let l = (l.clamp(0.0, 1.0) * 255.0) as u8; // Convert back to [0, 255] + *pixel = Luma([l]).to_rgba(); + } + let image = Image::new(image) .with_dither_palette(&[BLACK, WHITE]) .node()