mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-10 19:56:47 +03:00
Support saving PDF with different X and Y resolution.
Add a `dpi` parameter to the PDF save function, which accepts a tuple with X and Y dpi. This is useful for converting tiffg3 (fax) images to pdf, which have split dpi like (204,391), (204,196) or (204,98).
This commit is contained in:
parent
d48dca3dc4
commit
36bcc0a898
|
@ -80,6 +80,48 @@ def test_resolution(tmp_path):
|
|||
assert size == (61.44, 61.44)
|
||||
|
||||
|
||||
def test_dpi(tmp_path):
|
||||
im = hopper()
|
||||
|
||||
outfile = str(tmp_path / "temp.pdf")
|
||||
im.save(outfile, dpi=(75, 150))
|
||||
|
||||
with open(outfile, "rb") as fp:
|
||||
contents = fp.read()
|
||||
|
||||
size = tuple(
|
||||
float(d)
|
||||
for d in contents.split(b"stream\nq ")[1].split(b" 0 0 cm")[0].split(b" 0 0 ")
|
||||
)
|
||||
assert size == (122.88, 61.44)
|
||||
|
||||
size = tuple(
|
||||
float(d) for d in contents.split(b"/MediaBox [ 0 0 ")[1].split(b"]")[0].split()
|
||||
)
|
||||
assert size == (122.88, 61.44)
|
||||
|
||||
|
||||
def test_resolution_and_dpi(tmp_path):
|
||||
im = hopper()
|
||||
|
||||
outfile = str(tmp_path / "temp.pdf")
|
||||
im.save(outfile, resolution=200, dpi=(75, 150))
|
||||
|
||||
with open(outfile, "rb") as fp:
|
||||
contents = fp.read()
|
||||
|
||||
size = tuple(
|
||||
float(d)
|
||||
for d in contents.split(b"stream\nq ")[1].split(b" 0 0 cm")[0].split(b" 0 0 ")
|
||||
)
|
||||
assert size == (122.88, 61.44)
|
||||
|
||||
size = tuple(
|
||||
float(d) for d in contents.split(b"/MediaBox [ 0 0 ")[1].split(b"]")[0].split()
|
||||
)
|
||||
assert size == (122.88, 61.44)
|
||||
|
||||
|
||||
@mark_if_feature_version(
|
||||
pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing"
|
||||
)
|
||||
|
|
|
@ -1497,6 +1497,11 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum
|
|||
image, will determine the physical dimensions of the page that will be
|
||||
saved in the PDF.
|
||||
|
||||
**dpi**
|
||||
A tuple of (x_resolution, y_resolution), with inches as the resolution
|
||||
unit. If both the ``resolution`` parameter and the ``dpi`` parameter are
|
||||
present, ``resolution`` will be ignored.
|
||||
|
||||
**title**
|
||||
The document’s title. If not appending to an existing PDF file, this will
|
||||
default to the filename.
|
||||
|
|
|
@ -53,7 +53,12 @@ def _save(im, fp, filename, save_all=False):
|
|||
else:
|
||||
existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="w+b")
|
||||
|
||||
resolution = im.encoderinfo.get("resolution", 72.0)
|
||||
x_resolution = y_resolution = im.encoderinfo.get("resolution", 72.0)
|
||||
|
||||
dpi = im.encoderinfo.get("dpi")
|
||||
if dpi:
|
||||
x_resolution = dpi[0]
|
||||
y_resolution = dpi[1]
|
||||
|
||||
info = {
|
||||
"title": None
|
||||
|
@ -214,8 +219,8 @@ def _save(im, fp, filename, save_all=False):
|
|||
stream=stream,
|
||||
Type=PdfParser.PdfName("XObject"),
|
||||
Subtype=PdfParser.PdfName("Image"),
|
||||
Width=width, # * 72.0 / resolution,
|
||||
Height=height, # * 72.0 / resolution,
|
||||
Width=width, # * 72.0 / x_resolution,
|
||||
Height=height, # * 72.0 / y_resolution,
|
||||
Filter=filter,
|
||||
BitsPerComponent=bits,
|
||||
Decode=decode,
|
||||
|
@ -235,8 +240,8 @@ def _save(im, fp, filename, save_all=False):
|
|||
MediaBox=[
|
||||
0,
|
||||
0,
|
||||
width * 72.0 / resolution,
|
||||
height * 72.0 / resolution,
|
||||
width * 72.0 / x_resolution,
|
||||
height * 72.0 / y_resolution,
|
||||
],
|
||||
Contents=contents_refs[page_number],
|
||||
)
|
||||
|
@ -245,8 +250,8 @@ def _save(im, fp, filename, save_all=False):
|
|||
# page contents
|
||||
|
||||
page_contents = b"q %f 0 0 %f 0 0 cm /image Do Q\n" % (
|
||||
width * 72.0 / resolution,
|
||||
height * 72.0 / resolution,
|
||||
width * 72.0 / x_resolution,
|
||||
height * 72.0 / y_resolution,
|
||||
)
|
||||
|
||||
existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)
|
||||
|
|
Loading…
Reference in New Issue
Block a user