PDF presets: Press Quality converts to the document's profile, keeping its numbers (#2950)

Press Quality left Output at No conversion, so in a CMYK document RGB images went to the press as
DeviceRGB. It now converts to the destination with the numbers kept, the destination blank (the
document's profile): RGB comes out CMYK in a CMYK document, CMYK values stay exactly, RGB
documents are unchanged, and no profiles are included, as a printer's published [Press Quality]
settings list.
This commit is contained in:
00xJ0
2026-10-21 16:55:17 +07:00
committed by bflatastic
parent 0d4b597983
commit 5d0b966548
2 changed files with 30 additions and 4 deletions
+12 -4
View File
@@ -5,8 +5,8 @@
use serde::{Deserialize, Serialize};
use crate::{
BleedSettings, Compatibility, CompressionSettings, Downsample, ImageCodec, ImageCompression, JpegQuality, MonoCodec, MonoCompression,
PdfSettings, Standard,
BleedSettings, ColorConversion, Compatibility, CompressionSettings, Downsample, ImageCodec, ImageCompression, JpegQuality, MonoCodec,
MonoCompression, OutputSettings, PdfSettings, Standard,
};
/// The built-in preset every PDF export starts from.
@@ -62,10 +62,18 @@ pub fn builtin_presets() -> Vec<PdfPreset> {
PdfSettings { preserve_editing: true, ..Default::default() },
),
preset("High Quality Print", "For desktop printers and proofs: images stay at print resolution.", print(ImageCodec::Auto, false)),
// Converted to the document's profile, its own numbers kept: in a CMYK document RGB colours
// and images come out CMYK, as a press needs (#2950). A printer's published settings for
// the [Press Quality] preset list the same Output: Convert to Destination (Preserve
// Numbers), Document CMYK, no profiles included
// (https://postmediasolutions.com/hubfs/Website/Client%20Resources/PostmediaPrintPDFSpecSheet.pdf).
preset(
"Press Quality",
"For commercial printing: high-resolution images compressed losslessly, the document's bleed.",
print(ImageCodec::Zip, true),
"For commercial printing: high-resolution images compressed losslessly, the document's bleed, colours converted to the document's profile with its own numbers kept (RGB comes out CMYK in a CMYK document).",
PdfSettings {
output: OutputSettings { conversion: ColorConversion::PreserveNumbers, ..Default::default() },
..print(ImageCodec::Zip, true)
},
),
preset(
"Smallest File Size",
+18
View File
@@ -429,3 +429,21 @@ fn a_cmyk_image_masked_by_a_grey_image_of_its_grid_writes_it_as_its_smask() {
assert_eq!(smasks, [None]);
assert!(String::from_utf8_lossy(&bytes).contains("/S/Luminosity"), "a luminosity soft mask");
}
/// #2950: Press Quality converts to the document's profile with its numbers kept, so in a CMYK
/// document an RGB image comes out CMYK, as the press needs; with no conversion (the default
/// preset) it stays RGB, as before.
#[test]
fn press_quality_writes_an_rgb_image_in_a_cmyk_document_as_cmyk() {
let rgb = image::RgbImage::from_fn(4, 4, |x, y| image::Rgb([(x * 60) as u8, (y * 60) as u8, 128]));
let blob = ImageBlob { mime: "image/png".into(), bytes: Arc::new(png(rgb)), proxy: None };
let d = image_doc(blob, 4, 4);
let press = builtin_presets().into_iter().find(|p| p.name == "Press Quality").unwrap().settings;
assert_eq!(press.output.conversion, ColorConversion::PreserveNumbers);
let options = PdfOptions { settings: press, created: Some(1_700_000_000), ..Default::default() };
let w = written(&export_with_report(&d, &options).unwrap().bytes);
assert_eq!(w.len(), 1, "{w:?}");
assert_eq!((w[0].space.as_str(), w[0].icc_n), ("DeviceCMYK", None), "Press Quality");
let w = written(&export_with_report(&d, &opts(json!({}))).unwrap().bytes);
assert_eq!(w[0].space, "DeviceRGB", "no conversion");
}