fix: compressão real p/ stream DCTDecode + auth c/ chave vazia
- Substitui xobj._data por page.images[].replace() em compress.py e pdfa.py - Adiciona compress_with_stats() com feedback honesto na UI - Trata PDFTOOLKIT_API_KEY vazia como modo dev (auth desabilitado) - Atualiza engine.py e app.py para exibir redução real ou 'já otimizado'
This commit is contained in:
46
core/pdfa.py
46
core/pdfa.py
@@ -139,30 +139,36 @@ def strip_pdfa(data: bytes) -> bytes:
|
||||
def compress_pdfa(data: bytes, quality: int = 60, max_dim: int = 2000) -> bytes:
|
||||
"""
|
||||
Comprime imagens internas mantendo a estrutura PDF/A.
|
||||
Usa a mesma lógica de compress.compress_pdf mas preserva
|
||||
metadados XMP e OutputIntents.
|
||||
Usa a mesma lógica de compress_pdf (ImageFile.replace)
|
||||
mas preserva metadados XMP e OutputIntents.
|
||||
"""
|
||||
from .compress import _downsample_image
|
||||
from PIL import Image as PILImage
|
||||
from .compress import _prepare_image
|
||||
|
||||
reader = PdfReader(io.BytesIO(data))
|
||||
writer = PdfWriter()
|
||||
writer.metadata = reader.metadata
|
||||
writer = PdfWriter(clone_from=reader)
|
||||
|
||||
for page in reader.pages:
|
||||
if "/XObject" in page.get("/Resources", {}):
|
||||
xobjects = page["/Resources"]["/XObject"]
|
||||
for obj_name in list(xobjects.keys()):
|
||||
xobj = xobjects[obj_name]
|
||||
if xobj.get("/Subtype") == "/Image":
|
||||
try:
|
||||
raw = xobj.get_data()
|
||||
if raw:
|
||||
compressed = _downsample_image(raw, quality, max_dim)
|
||||
xobj._data = compressed
|
||||
except Exception:
|
||||
pass
|
||||
writer.add_page(page)
|
||||
replaced = 0
|
||||
for page in writer.pages:
|
||||
try:
|
||||
images = list(page.images)
|
||||
except Exception:
|
||||
continue
|
||||
for img_file in images:
|
||||
if getattr(img_file, "indirect_reference", None) is None:
|
||||
continue
|
||||
try:
|
||||
pil = img_file.image
|
||||
if pil is None:
|
||||
continue
|
||||
prepared, save_kwargs = _prepare_image(
|
||||
pil, quality=quality, max_dim=max_dim
|
||||
)
|
||||
img_file.replace(prepared, **save_kwargs)
|
||||
replaced += 1
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
out_buf = io.BytesIO()
|
||||
writer.write_stream(out_buf)
|
||||
writer.write(out_buf)
|
||||
return out_buf.getvalue()
|
||||
Reference in New Issue
Block a user