Add fallback if ImageMagick is not available
This commit is contained in:
@@ -5,6 +5,14 @@ import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict
|
||||
|
||||
try:
|
||||
import fitz # PyMuPDF
|
||||
_PYMUPDF_AVAILABLE = True
|
||||
except ImportError:
|
||||
_PYMUPDF_AVAILABLE = False
|
||||
|
||||
_IMAGEMAGICK_AVAILABLE = shutil.which("convert") is not None
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from gallery.utils.metadata import (
|
||||
@@ -184,17 +192,15 @@ def render_gallery_page(
|
||||
|
||||
def convert_pdf_to_png(pdf_path: Path, config: GalleryConfig) -> None:
|
||||
"""
|
||||
Convert a PDF file to PNG format using ImageMagick.
|
||||
Convert a PDF file to PNG format.
|
||||
|
||||
Uses PyMuPDF (fitz) when available; falls back to ImageMagick otherwise.
|
||||
Only converts if the PNG doesn't exist or if the PDF is newer than
|
||||
the PNG (with a 30-second buffer to handle filesystem timing issues).
|
||||
|
||||
Args:
|
||||
pdf_path: Path to the source PDF file
|
||||
config: Gallery configuration object
|
||||
|
||||
Raises:
|
||||
subprocess.CalledProcessError: If ImageMagick conversion fails
|
||||
RuntimeError: If neither PyMuPDF nor ImageMagick is available.
|
||||
subprocess.CalledProcessError: If the ImageMagick fallback fails.
|
||||
"""
|
||||
png_path = pdf_path.with_suffix(".png")
|
||||
|
||||
@@ -204,12 +210,34 @@ def convert_pdf_to_png(pdf_path: Path, config: GalleryConfig) -> None:
|
||||
if png_mtime >= (pdf_mtime + 30):
|
||||
return
|
||||
|
||||
if _PYMUPDF_AVAILABLE:
|
||||
_convert_pdf_pymupdf(pdf_path, png_path, config.png_dpi)
|
||||
elif _IMAGEMAGICK_AVAILABLE:
|
||||
_convert_pdf_imagemagick(pdf_path, png_path, config.png_dpi)
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"No PDF renderer found. Install PyMuPDF (`pip install pymupdf`) "
|
||||
"or ImageMagick (`apt-get install imagemagick`)."
|
||||
)
|
||||
|
||||
|
||||
def _convert_pdf_pymupdf(pdf_path: Path, png_path: Path, dpi: int) -> None:
|
||||
zoom = dpi / 72 # PDF coordinate space is 72 pt/inch
|
||||
doc = fitz.open(str(pdf_path))
|
||||
try:
|
||||
pix = doc[0].get_pixmap(matrix=fitz.Matrix(zoom, zoom))
|
||||
pix.save(str(png_path))
|
||||
finally:
|
||||
doc.close()
|
||||
|
||||
|
||||
def _convert_pdf_imagemagick(pdf_path: Path, png_path: Path, dpi: int) -> None:
|
||||
subprocess.run([
|
||||
"convert",
|
||||
"-density", str(config.png_dpi),
|
||||
"-density", str(dpi),
|
||||
str(pdf_path),
|
||||
"-quality", "95",
|
||||
str(png_path)
|
||||
str(png_path),
|
||||
], check=True)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user