Supporte les PDF comme images à mettre en gabarit.
This commit is contained in:
@@ -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
|
||||
|
||||
|
41
app/app.py
41
app/app.py
@@ -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)
|
||||
|
||||
|
@@ -1,2 +1,4 @@
|
||||
flask
|
||||
fpdf2
|
||||
fpdf2
|
||||
PyPDF2
|
||||
pdf2image
|
@@ -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">
|
||||
|
@@ -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`)>
|
Reference in New Issue
Block a user