AiAnonymize_v3 / pdf /rendering /png_method.py
Alessandro Tomassini
deploy(hf): overlay README/Dockerfile da huggingface/, senza docs/binari/model
c42a5a1
Raw
History Blame Contribute Delete
2.7 kB
"""Metodo C — rendering PNG rasterizzato server-side."""
from __future__ import annotations
from pdf.rendering import _raster
from pdf.rendering.base import (
MethodInfo,
RenderKind,
RenderMethod,
RenderOutput,
RenderParams,
boxes_on_page,
)
from pdf.rendering.styles import severity_rgb
class PngRenderMethod(RenderMethod):
info = MethodInfo(
key="png",
label="C · PNG",
kind=RenderKind.VIEW,
media_type="image/png",
styles=("fill", "outline", "label", "pixelate", "blur"),
default_style="fill",
description=(
"Pagina rasterizzata dal server con box disegnati sulla bitmap. "
"Funziona con qualsiasi PDF; supporta mosaico e sfocatura."
),
)
def render(self, params: RenderParams) -> RenderOutput:
import fitz
import numpy as np
doc = fitz.open(stream=params.pdf_bytes, filetype="pdf")
page = doc.load_page(params.page)
scale = params.dpi / 72.0
pix = page.get_pixmap(matrix=fitz.Matrix(scale, scale), alpha=False)
doc.close()
h, w, n = pix.height, pix.width, pix.n
arr = np.frombuffer(pix.samples, dtype=np.uint8).reshape(h, w, n).copy()
for b in boxes_on_page(params):
x0 = max(0, int(b["x0"] * scale))
y0 = max(0, int(b["y0"] * scale))
x1 = min(w, int(b["x1"] * scale))
y1 = min(h, int(b["y1"] * scale))
if x1 <= x0 or y1 <= y0:
continue
r, g, bl = severity_rgb(b.get("severity", "media"))
color = np.array([r * 255, g * 255, bl * 255], dtype=np.float32)
region = arr[y0:y1, x0:x1, :3].astype(np.float32)
if params.style == "pixelate":
arr[y0:y1, x0:x1, :3] = _raster.pixelate(region).astype(np.uint8)
elif params.style == "blur":
arr[y0:y1, x0:x1, :3] = _raster.box_blur(region).astype(np.uint8)
elif params.style == "outline":
_raster.draw_outline(arr, x0, y0, x1, y1, color, thickness=max(2, int(scale)))
else: # fill / label
arr[y0:y1, x0:x1, :3] = _raster.alpha_fill(
region, color, params.opacity
).astype(np.uint8)
out_pix = fitz.Pixmap(pix.colorspace, pix.width, pix.height, arr.tobytes(), pix.alpha)
return RenderOutput(
data=out_pix.tobytes("png"),
media_type=self.info.media_type,
headers={
"X-Page-Width-Px": str(w),
"X-Page-Height-Px": str(h),
"Cache-Control": "private, max-age=300",
},
)