Supporte les PDF comme images à mettre en gabarit.

This commit is contained in:
2024-10-19 17:18:58 +02:00
parent 1abf817510
commit f280ec56af
5 changed files with 46 additions and 14 deletions

View File

@@ -3,6 +3,7 @@ FROM python:3.10-alpine
WORKDIR /app
COPY requirements.txt /app
RUN apk add py3-pdf2image
RUN --mount=type=cache,target=/root/.cache/pip \
pip3 install -r requirements.txt

View File

@@ -5,9 +5,23 @@ import io
import zipfile
from werkzeug.datastructures import FileStorage
from PIL import Image
from pdf2image import convert_from_bytes
from PyPDF2 import PdfReader
VALID_KIND = ["all", "tc", "zc", "zip"]
ALLOWED_EXTENSIONS = ["png", "jpeg", "jpg"]
ALLOWED_EXTENSIONS = ["png", "jpeg", "jpg", "pdf"]
# Function to get the dimensions of the source PDF page
def get_page_dimensions(pdfData, page_number=0):
reader = PdfReader(pdfData)
page = reader.pages[page_number]
width = float(page.mediabox.width)
height = float(page.mediabox.height)
width = width * (page.user_unit / 72) * 25.4
height = height * (page.user_unit / 72) * 25.4
return width, height
def generateTemplate(width: int, height: int, fondPerdu: int, zoneTranquille: int, marge: int, kind: str = "all", image: FileStorage = None, aFondPerdu: bool = False) -> fpdf.FPDF:
@@ -20,15 +34,27 @@ def generateTemplate(width: int, height: int, fondPerdu: int, zoneTranquille: in
pdf.set_auto_page_break(False)
pdf.add_page()
if (image):
xy, w, h = margeDuContenue, width, height
if (aFondPerdu == True):
xy = xy - fondPerdu
w = w + fondPerdu*2
h = h + fondPerdu*2
if (image and image.mimetype in ["image/jpeg", "image/png"]):
if 'inMemoryImage' not in flask.g:
flask.g.inMemoryImage = io.BytesIO()
image.save(flask.g.inMemoryImage)
xy, w, h = margeDuContenue, width, height
if (aFondPerdu == True):
xy = xy - fondPerdu
w = w + fondPerdu*2
h = h + fondPerdu*2
if (image and image.mimetype in ["application/pdf", "application/x-pdf"]):
if 'inMemoryImage' not in flask.g:
pdfData = image.stream.read()
pdfW, pdfH = get_page_dimensions(io.BytesIO(pdfData))
scale = min(pdfW/w, pdfH/h)
imageFromPDF = convert_from_bytes(
pdfData, dpi=600, size=(w*scale, h*scale), single_file=True)
flask.g.inMemoryImage = imageFromPDF[0]
if ('inMemoryImage' in flask.g):
pdf.image(flask.g.inMemoryImage, xy, xy, w, h, keep_aspect_ratio=True)
if (kind in ["all", "zc"]):
@@ -151,4 +177,3 @@ def generate():
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)

View File

@@ -1,2 +1,4 @@
flask
fpdf2
PyPDF2
pdf2image

View File

@@ -86,14 +86,16 @@
<label for="rb_tc">Traits de coupe</label><input required type="radio" value="tc" name="kind" id="rb_tc">
<label for="rb_zc">Zone de construction</label><input required type="radio" value="zc" name="kind"
id="rb_zc">
<label for="rb_all">Zone de construction & traits de coupe</label><input required type="radio" value="all" name="kind" id="rb_all">
<label for="rb_zip">ZIP (3 PDF en 1 clique)</label><input required type="radio" value="zip" name="kind" id="rb_zip" checked>
<label for="rb_all">Zone de construction & traits de coupe</label><input required type="radio" value="all"
name="kind" id="rb_all">
<label for="rb_zip">ZIP (3 PDF en 1 clique)</label><input required type="radio" value="zip" name="kind"
id="rb_zip" checked>
</div>
<div class="two-col">
<span>
<span class="sectionTitle">Mettre en gabarit</span>
<span><br />PNG ou JPEG uniquement</span></span>
<input type="file" name="file" accept="image/png, image/jpeg">
<span><br />PNG, JPEG ou PDF uniquement</span></span>
<input type="file" name="file" accept="image/png, image/jpeg, application/pdf, application/x-pdf">
<label for="cb_fp">Fond perdu</label><input type="checkbox" name="ffp">
</div>
<input type="submit" value="Générer">

View File

@@ -7,6 +7,8 @@ services:
# flask requires SIGINT to stop gracefully
# (default stop signal from Compose is SIGTERM)
stop_signal: SIGINT
ports:
- 5000:8000
labels:
traefik.enable: true
traefik.http.routers.templatepdf.rule: Host(`template.ar2000.me`)
traefik.http.routers.templatepdf.rule: Host(`template.ar2000.me`)>