mirror of
https://github.com/typst/typst
synced 2025-05-15 01:25:28 +08:00
Fix PDF export of grayscale image (#3219)
This commit is contained in:
parent
b4b17871d6
commit
11abc1f1e3
@ -113,42 +113,24 @@ pub(crate) fn write_images(ctx: &mut PdfContext) {
|
|||||||
/// Skips the alpha channel as that's encoded separately.
|
/// Skips the alpha channel as that's encoded separately.
|
||||||
fn encode_raster_image(image: &RasterImage) -> (Vec<u8>, Filter, bool) {
|
fn encode_raster_image(image: &RasterImage) -> (Vec<u8>, Filter, bool) {
|
||||||
let dynamic = image.dynamic();
|
let dynamic = image.dynamic();
|
||||||
match (image.format(), dynamic) {
|
let channel_count = dynamic.color().channel_count();
|
||||||
// 8-bit gray JPEG.
|
let has_color = channel_count > 2;
|
||||||
(RasterFormat::Jpg, DynamicImage::ImageLuma8(_)) => {
|
|
||||||
let mut data = Cursor::new(vec![]);
|
|
||||||
dynamic.write_to(&mut data, image::ImageFormat::Jpeg).unwrap();
|
|
||||||
(data.into_inner(), Filter::DctDecode, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8-bit RGB JPEG (CMYK JPEGs get converted to RGB earlier).
|
|
||||||
(RasterFormat::Jpg, DynamicImage::ImageRgb8(_)) => {
|
|
||||||
let mut data = Cursor::new(vec![]);
|
|
||||||
dynamic.write_to(&mut data, image::ImageFormat::Jpeg).unwrap();
|
|
||||||
(data.into_inner(), Filter::DctDecode, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if image.format() == RasterFormat::Jpg {
|
||||||
|
let mut data = Cursor::new(vec![]);
|
||||||
|
dynamic.write_to(&mut data, image::ImageFormat::Jpeg).unwrap();
|
||||||
|
(data.into_inner(), Filter::DctDecode, has_color)
|
||||||
|
} else {
|
||||||
// TODO: Encode flate streams with PNG-predictor?
|
// TODO: Encode flate streams with PNG-predictor?
|
||||||
|
let data = match (dynamic, channel_count) {
|
||||||
// 8-bit gray PNG.
|
(DynamicImage::ImageLuma8(luma), _) => deflate(luma.as_raw()),
|
||||||
(RasterFormat::Png, DynamicImage::ImageLuma8(luma)) => {
|
(DynamicImage::ImageRgb8(rgb), _) => deflate(rgb.as_raw()),
|
||||||
let data = deflate(luma.as_raw());
|
// Grayscale image
|
||||||
(data, Filter::FlateDecode, false)
|
(_, 1 | 2) => deflate(dynamic.to_luma8().as_raw()),
|
||||||
}
|
// Anything else
|
||||||
|
_ => deflate(dynamic.to_rgb8().as_raw()),
|
||||||
// Anything else (including Rgb(a) PNGs).
|
};
|
||||||
(_, buf) => {
|
(data, Filter::FlateDecode, has_color)
|
||||||
let (width, height) = buf.dimensions();
|
|
||||||
let mut pixels = Vec::with_capacity(3 * width as usize * height as usize);
|
|
||||||
for (_, _, Rgba([r, g, b, _])) in buf.pixels() {
|
|
||||||
pixels.push(r);
|
|
||||||
pixels.push(g);
|
|
||||||
pixels.push(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = deflate(&pixels);
|
|
||||||
(data, Filter::FlateDecode, true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user