| ... | @@ -53,12 +53,10 @@ pub(crate) fn pixels(encoded: &[u8]) -> Result<([u32; 2], Vec<u8>), Box<dyn Erro | ... | @@ -53,12 +53,10 @@ pub(crate) fn pixels(encoded: &[u8]) -> Result<([u32; 2], Vec<u8>), Box<dyn Erro |
| 53 | .map_err(|error| format!("{error:?}"))?; | 53 | .map_err(|error| format!("{error:?}"))?; |
| 54 | let mut rgba = image.pixels().to_vec(); | 54 | let mut rgba = image.pixels().to_vec(); |
| 55 | for pixel in rgba.chunks_exact_mut(4) { | 55 | for pixel in rgba.chunks_exact_mut(4) { |
| 56 | let alpha = u32::from(pixel[3]); | 56 | if pixel[3] != 255 { |
| 57 | for channel in &mut pixel[..3] { | 57 | let scale = 255.0 / f32::from(pixel[3].max(1)); |
| 58 | *channel = (u32::from(*channel) * 255 + alpha / 2) | 58 | let linear = draw::srgb(pixel[0], pixel[1], pixel[2]).map(|v| v * scale); |
| 59 | .checked_div(alpha) | 59 | pixel[..3].copy_from_slice(&draw::srgb_bytes(linear)); |
| 60 | .unwrap_or(0) | | |
| 61 | .min(255) as u8; | | |
| 62 | } | 60 | } |
| 63 | } | 61 | } |
| 64 | return Ok((image.size(), rgba)); | 62 | return Ok((image.size(), rgba)); |
| ... | @@ -487,6 +485,22 @@ mod tests { | ... | @@ -487,6 +485,22 @@ mod tests { |
| 487 | assert_eq!(pixels(&encoded).unwrap(), ([2, 1], rgba.to_vec())); | 485 | assert_eq!(pixels(&encoded).unwrap(), ([2, 1], rgba.to_vec())); |
| 488 | } | 486 | } |
| 489 | | 487 | |
| | 488 | #[test] |
| | 489 | fn clipboard_pixels_keep_translucent_tiff_colors() { |
| | 490 | use image::ImageEncoder; |
| | 491 | let rgba = [220, 120, 80, 128]; |
| | 492 | let mut encoded = Vec::new(); |
| | 493 | image::codecs::tiff::TiffEncoder::new(std::io::Cursor::new(&mut encoded)) |
| | 494 | .write_image(&rgba, 1, 1, image::ExtendedColorType::Rgba8) |
| | 495 | .unwrap(); |
| | 496 | let (size, decoded) = pixels(&encoded).unwrap(); |
| | 497 | assert_eq!(size, [1, 1]); |
| | 498 | assert_eq!(decoded[3], rgba[3]); |
| | 499 | for (actual, expected) in decoded[..3].iter().zip(&rgba[..3]) { |
| | 500 | assert!(actual.abs_diff(*expected) <= 2, "{decoded:?}"); |
| | 501 | } |
| | 502 | } |
| | 503 | |
| 490 | fn png_at(pixels_per_metre: Option<u32>) -> Vec<u8> { | 504 | fn png_at(pixels_per_metre: Option<u32>) -> Vec<u8> { |
| 491 | let mut bytes = Vec::new(); | 505 | let mut bytes = Vec::new(); |
| 492 | let mut encoder = png::Encoder::new(&mut bytes, 200, 100); | 506 | let mut encoder = png::Encoder::new(&mut bytes, 200, 100); |