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
107
108
109
110
111
112
113
114
115
116 | """Places every picture a TIFF holds on a page of its own, and writes the result to
disk.
The Python twin of the `write_tiff` example in Rust.
A TIFF holds any number of pictures, one directory apiece: a scanner puts every sheet
of a batch in one file, and a fax puts every page of a call there. Each of them gets a
page exactly its own size — at 72 dots to the inch one pixel is one point — so the page
that comes back out of a renderer is the picture that went in.
Named nothing, the example reads the two committed fixtures: one holding a photograph
in a single strip, whose bytes go into the document undecoded because PDF reads a
photograph itself, and one holding three pictures whose samples are read and written
again. It opens on a sheet laying all of them out the way a document would.
Usage: python examples/write_tiff.py [out.pdf] [file.tif...]
"""
from __future__ import annotations
import sys
from pathlib import Path
import _licence
import _out
import hqf_pdf
# The files the example reads 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_FILES = [IMAGES / "photograph.tif", IMAGES / "pages.tif"]
# How wide the sheet the showcase is laid out on is.
A4_WIDTH = 595.276
# The side of the box each picture of the showcase is fitted into, and how far apart the
# boxes stand.
BOX_SIDE = 120.0
BOX_STEP = 130.0
def sheet_of_all(handles: list) -> hqf_pdf.Page:
"""One sheet holding every picture the files gave, each fitted whole into a box of
one size and standing on the same line as the rest."""
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()
left = 60.0
for handle in handles:
width, height = handle.fit_within(BOX_SIDE, BOX_SIDE)
content.draw_image(handle, left, 600.0, width, height)
left += BOX_STEP
page = hqf_pdf.Page.a4()
page.set_content(content)
return page
def main() -> None:
out = _out.output_path("tiff")
named = [Path(argument) for argument in sys.argv[2:]]
showcase = not named
paths = DEFAULT_FILES if showcase else named
doc = hqf_pdf.Document()
doc.set_license(_licence.licensed())
doc.set_info("Title", "hqf-pdf TIFF sample")
handles = []
for path in paths:
data = path.read_bytes()
held = hqf_pdf.Image.tiff_pages(data)
print(f"{path}: {held} picture(s)")
for page in range(held):
image = hqf_pdf.Image.from_tiff_page(data, page)
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"
)
print(
f" {page + 1}: {image.width}x{image.height} {image.color_space!r},"
f" {image.bits_per_component} bits a component, {declared}"
)
handles.append(doc.add_image(image))
if showcase:
doc.add_page(sheet_of_all(handles))
for handle in handles:
# A page the size of the picture, with the picture 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)
sheet = hqf_pdf.Page(width, height)
sheet.set_content(content)
doc.add_page(sheet)
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()
|