1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 | """Places images on a page, and writes the result to disk.
The Python twin of the `write_image` example in Rust.
Each image named on the command line gets a page of its own, exactly as big as the
image is: at 72 dots to the inch one pixel is one point, so the page that comes back
out of a renderer is the image that went in.
Named nothing, the example places the two committed fixtures — a JPEG, whose bytes go
into the file undecoded, and a PNG whose transparency becomes a soft mask — and adds a
page that lays them out the way a document would.
Usage: python examples/write_image.py [out.pdf] [image...]
"""
from __future__ import annotations
import sys
from pathlib import Path
import _licence
import _out
import hqf_pdf
# The images the example places when the caller names none: the ones committed for the
# tests, so that it runs on any machine.
IMAGES = Path(__file__).resolve().parents[2] / "hqf-pdf" / "tests" / "images"
DEFAULT_IMAGES = [IMAGES / "photo.jpg", IMAGES / "logo.png"]
A4_WIDTH = 595.276
def main() -> None:
out = _out.output_path("image")
named = [Path(argument) for argument in sys.argv[2:]]
showcase = not named
paths = DEFAULT_IMAGES if showcase else named
doc = hqf_pdf.Document()
doc.set_license(_licence.licensed())
doc.set_info("Title", "hqf-pdf image sample")
handles = []
for path in paths:
image = hqf_pdf.Image.from_path(path)
resolution = image.resolution
declared = (
f"{resolution.x} by {resolution.y} dots to the inch"
if resolution is not None
else "stating no resolution of its own"
)
orientation = image.orientation
way_up = f"seen {orientation!r}" if orientation is not None else "and no way up"
print(
f"{path}: {image.width}x{image.height}"
f"{', with a soft mask' if image.has_alpha else ''}, {declared}, {way_up}"
)
handle = doc.add_image(image)
# A page the size of the image, with the image filling it. The size is the one
# the file itself asks for; a file asking for none is laid down one pixel to the
# point.
width, height = handle.size
content = hqf_pdf.Content()
content.draw_image(handle, 0.0, 0.0, width, height)
page = hqf_pdf.Page(width, height)
page.set_content(content)
doc.add_page(page)
handles.append(handle)
if showcase:
# One more page, laid out the way a document would lay it out: the photo fitted
# into a box without being stretched, and the logo, whose transparency lets what
# is under it show through.
content = hqf_pdf.Content()
content.set_fill(hqf_pdf.Rgb(0.93, 0.94, 0.96))
content.rect(0.0, 700.0, A4_WIDTH, 142.0)
content.fill()
photo, logo = handles[0], handles[1]
width, height = photo.fit_within(240.0, 160.0)
content.draw_image(photo, 60.0, 500.0, width, height)
width, height = logo.fit_within(90.0, 90.0)
content.draw_image(logo, 380.0, 730.0, width, height)
page = hqf_pdf.Page.a4()
page.set_content(content)
doc.add_page(page)
pdf = doc.to_bytes()
Path(out).parent.mkdir(parents=True, exist_ok=True)
Path(out).write_bytes(pdf)
print(f"wrote {out}: {len(pdf)} bytes, {doc.page_count} page(s)")
if __name__ == "__main__":
main()
|