"""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", }, )