Skip to content

Commit 194ce41

Browse files
Merge pull request #193 from chinapandaman/PPF-190
PPF-190: any image to jpg
2 parents 9620f9c + 460276d commit 194ce41

11 files changed

+116
-1
lines changed

PyPDFForm/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
PyPDFForm = Wrapper
66

7-
__version__ = "0.3.2"
7+
__version__ = "0.3.3"

PyPDFForm/core/image.py

+23
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,26 @@ def rotate_image(image_stream: bytes, rotation: Union[float, int]) -> bytes:
4848
rotated_buff.close()
4949

5050
return result
51+
52+
@staticmethod
53+
def any_image_to_jpg(image_stream: bytes) -> bytes:
54+
"""Converts an image of any type to jpg."""
55+
56+
buff = BytesIO()
57+
buff.write(image_stream)
58+
buff.seek(0)
59+
60+
image = Img.open(buff)
61+
62+
if image.format == "JPEG":
63+
buff.close()
64+
return image_stream
65+
66+
rgb_image = image.convert("RGB")
67+
with BytesIO() as f:
68+
rgb_image.save(f, format="JPEG")
69+
f.seek(0)
70+
result = f.read()
71+
72+
buff.close()
73+
return result

PyPDFForm/middleware/wrapper.py

+5
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ def _fill(
120120
self.elements[key].validate_constants()
121121
self.elements[key].validate_value()
122122
self.elements[key].validate_text_attributes()
123+
if self.elements[key].type == ElementType.image:
124+
value = ImageCore().any_image_to_jpg(value)
125+
self.elements[key].value = value
123126

124127
self.stream = FillerCore().fill(self.stream, self.elements)
125128

@@ -151,6 +154,7 @@ def _simple_fill(
151154
if isinstance(value, bytes):
152155
if not ImageCore().is_image(value):
153156
raise InvalidFormDataError
157+
data[key] = ImageCore().any_image_to_jpg(value)
154158

155159
if not isinstance(editable, bool):
156160
raise InvalidEditableParameterError
@@ -243,6 +247,7 @@ def draw_image(
243247
if not ImageCore().is_image(image):
244248
raise InvalidImageError
245249

250+
image = ImageCore().any_image_to_jpg(image)
246251
image = ImageCore().rotate_image(image, rotation)
247252

248253
if not isinstance(page_number, int):

image_samples/after_converted.jpg

48 KB
Loading

image_samples/before_converted.png

21.5 KB
Loading
825 KB
Binary file not shown.
Binary file not shown.
671 KB
Binary file not shown.

tests/functional/test_draw_on_pdf.py

+20
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,23 @@ def test_draw_image_on_one_page_f_obj_param(
132132
assert obj.stream == expected
133133
else:
134134
assert obj.stream[:32767] == expected[:32767]
135+
136+
137+
def test_draw_png_image_on_one_page(template_stream, image_samples, pdf_samples):
138+
with open(os.path.join(pdf_samples, "sample_pdf_with_png_image.pdf"), "rb+") as f:
139+
obj = PyPDFForm(template_stream).draw_image(
140+
os.path.join(image_samples, "before_converted.png"),
141+
2,
142+
100,
143+
100,
144+
400,
145+
225,
146+
)
147+
148+
expected = f.read()
149+
150+
if os.name == "nt":
151+
assert len(obj.stream) == len(expected)
152+
assert obj.stream == expected
153+
else:
154+
assert obj.stream[:32767] == expected[:32767]

tests/functional/test_fill.py

+45
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,51 @@ def test_fill_images_f_obj_params_explicitly_setting_elements(
522522
assert obj.stream[:32767] == expected[:32767]
523523

524524

525+
def test_fill_png_images(pdf_samples, image_samples):
526+
with open(os.path.join(pdf_samples, "sample_filled_png_images.pdf"), "rb+") as f:
527+
expected = f.read()
528+
529+
obj = PyPDFForm(
530+
os.path.join(pdf_samples, "sample_template_with_image_field.pdf"),
531+
simple_mode=False,
532+
).fill(
533+
{
534+
"image_1": os.path.join(image_samples, "before_converted.png"),
535+
"image_2": os.path.join(image_samples, "before_converted.png"),
536+
"image_3": os.path.join(image_samples, "before_converted.png"),
537+
}
538+
)
539+
540+
if os.name == "nt":
541+
assert len(obj.stream) == len(expected)
542+
assert obj.stream == expected
543+
else:
544+
assert obj.stream[:16383] == expected[:16383]
545+
546+
547+
def test_simple_fill_png_images(pdf_samples, image_samples):
548+
with open(
549+
os.path.join(pdf_samples, "sample_filled_png_images_simple_mode.pdf"), "rb+"
550+
) as f:
551+
expected = f.read()
552+
553+
obj = PyPDFForm(
554+
os.path.join(pdf_samples, "sample_template_with_image_field.pdf"),
555+
).fill(
556+
{
557+
"image_1": os.path.join(image_samples, "before_converted.png"),
558+
"image_2": os.path.join(image_samples, "before_converted.png"),
559+
"image_3": os.path.join(image_samples, "before_converted.png"),
560+
}
561+
)
562+
563+
if os.name == "nt":
564+
assert len(obj.stream) == len(expected)
565+
assert obj.stream == expected
566+
else:
567+
assert obj.stream[:16383] == expected[:16383]
568+
569+
525570
def test_simple_fill_radiobutton(pdf_samples, template_with_radiobutton_stream):
526571
with open(
527572
os.path.join(pdf_samples, "sample_filled_radiobutton_simple.pdf"), "rb+"

tests/unit/test_image.py

+22
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ def image_stream(image_samples):
2525
return f.read()
2626

2727

28+
@pytest.fixture
29+
def before_converted(image_samples):
30+
with open(os.path.join(image_samples, "before_converted.png"), "rb+") as f:
31+
return f.read()
32+
33+
34+
@pytest.fixture
35+
def after_converted(image_samples):
36+
with open(os.path.join(image_samples, "after_converted.jpg"), "rb+") as f:
37+
return f.read()
38+
39+
2840
def test_is_image(image_stream):
2941
assert not ImageCore().is_image(b"bad_stream")
3042
assert ImageCore().is_image(image_stream)
@@ -47,3 +59,13 @@ def test_rotate_image(image_stream):
4759

4860
buff.close()
4961
rotated_buff.close()
62+
63+
64+
def test_any_image_to_jpg(before_converted, after_converted):
65+
if os.name == "nt":
66+
assert ImageCore().any_image_to_jpg(before_converted) == after_converted
67+
else:
68+
assert (
69+
ImageCore().any_image_to_jpg(before_converted)[:511]
70+
== after_converted[:511]
71+
)

0 commit comments

Comments
 (0)