fix: normalize raster images before img2pdf retry
img2pdf refuses images with alpha channels or more than 8 bits per channel (common for screenshots). Normalize such images to opaque 8-bit with ImageMagick and retry img2pdf before falling back to a full ImageMagick PDF conversion.
This commit is contained in:
parent
481f1ed702
commit
a3c87fcde4
1 changed files with 37 additions and 1 deletions
38
src/main.rs
38
src/main.rs
|
|
@ -842,7 +842,8 @@ fn path_hash(path: &Path) -> u64 {
|
|||
/// Print the currently active document to the system printer via CUPS (lp).
|
||||
///
|
||||
/// - **PDF** → sent directly to CUPS via `lp`
|
||||
/// - **Raster images** → converted to PDF via `img2pdf` (or `convert` as fallback)
|
||||
/// - **Raster images** → converted to PDF via `img2pdf` (normalized to
|
||||
/// opaque 8-bit when needed, or `convert` as fallback)
|
||||
/// - **SVG** → converted to PDF via `pdftocairo` → `img2pdf`
|
||||
fn print_document_sync(path: &Path, kind: DocumentKind) -> Result<(), String> {
|
||||
let pdf_path = match kind {
|
||||
|
|
@ -861,10 +862,45 @@ fn convert_raster_to_pdf(path: &Path) -> Result<PathBuf, String> {
|
|||
return Ok(result);
|
||||
}
|
||||
|
||||
// img2pdf refuses alpha channels and >8 bit channels: normalize to
|
||||
// opaque 8-bit and retry before falling back to ImageMagick.
|
||||
if let Ok(normalized) = normalize_raster(path) {
|
||||
let result = convert_with_cmd(
|
||||
"img2pdf",
|
||||
vec![normalized.to_string_lossy().into_owned()],
|
||||
path,
|
||||
);
|
||||
let _ = std::fs::remove_file(&normalized);
|
||||
if let Ok(result) = result {
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: ImageMagick convert
|
||||
convert_with_cmd("convert", vec![path.to_string_lossy().into_owned()], path)
|
||||
}
|
||||
|
||||
fn normalize_raster(path: &Path) -> Result<PathBuf, String> {
|
||||
let extension = path.extension().and_then(OsStr::to_str).unwrap_or("png");
|
||||
let output_path = temp_prefix(path, "normalized").with_extension(extension);
|
||||
|
||||
let status = Command::new("convert")
|
||||
.arg(path)
|
||||
.args(["-depth", "8", "-alpha", "off"])
|
||||
.arg(&output_path)
|
||||
.status()
|
||||
.map_err(|e| format!("Failed to run convert: {e}"))?;
|
||||
if !status.success() {
|
||||
return Err("convert failed".to_string());
|
||||
}
|
||||
|
||||
if output_path.exists() {
|
||||
Ok(output_path)
|
||||
} else {
|
||||
Err("convert did not produce output".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_svg_to_pdf(path: &Path) -> Result<PathBuf, String> {
|
||||
// Render SVG to PNG with pdftocairo, then convert PNG to PDF
|
||||
let prefix = temp_prefix(path, "svg");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue