Save 1 mode PDF using CCITTFaxDecode filter

This commit is contained in:
Andrew Murray 2022-08-01 20:38:47 +10:00
parent 7e7a48479b
commit f5b27f90f7
2 changed files with 36 additions and 10 deletions

View File

@ -43,7 +43,7 @@ def test_monochrome(tmp_path):
# Act / Assert
outfile = helper_save_as_pdf(tmp_path, mode)
assert os.path.getsize(outfile) < 15000
assert os.path.getsize(outfile) < 5000
def test_greyscale(tmp_path):

View File

@ -21,10 +21,11 @@
##
import io
import math
import os
import time
from . import Image, ImageFile, ImageSequence, PdfParser, __version__
from . import Image, ImageFile, ImageSequence, PdfParser, TiffImagePlugin, __version__
#
# --------------------------------------------------------------------
@ -123,8 +124,26 @@ def _save(im, fp, filename, save_all=False):
params = None
decode = None
#
# Get image characteristics
width, height = im.size
if im.mode == "1":
filter = "DCTDecode"
filter = "CCITTFaxDecode"
bits = 1
params = PdfParser.PdfArray(
[
PdfParser.PdfDict(
{
"K": -1,
"BlackIs1": True,
"Columns": width,
"Rows": height,
}
)
]
)
colorspace = PdfParser.PdfName("DeviceGray")
procset = "ImageB" # grayscale
elif im.mode == "L":
@ -161,6 +180,11 @@ def _save(im, fp, filename, save_all=False):
if filter == "ASCIIHexDecode":
ImageFile._save(im, op, [("hex", (0, 0) + im.size, 0, im.mode)])
elif filter == "CCITTFaxDecode":
original_strip_size = TiffImagePlugin.STRIP_SIZE
TiffImagePlugin.STRIP_SIZE = math.ceil(im.width / 8) * im.height
im.save(op, "TIFF", compression="group4")
TiffImagePlugin.STRIP_SIZE = original_strip_size
elif filter == "DCTDecode":
Image.SAVE["JPEG"](im, op, filename)
elif filter == "FlateDecode":
@ -170,22 +194,24 @@ def _save(im, fp, filename, save_all=False):
else:
raise ValueError(f"unsupported PDF filter ({filter})")
#
# Get image characteristics
width, height = im.size
stream = op.getvalue()
if filter == "CCITTFaxDecode":
stream = stream[8:]
filter = PdfParser.PdfArray([PdfParser.PdfName(filter)])
else:
filter = PdfParser.PdfName(filter)
existing_pdf.write_obj(
image_refs[page_number],
stream=op.getvalue(),
stream=stream,
Type=PdfParser.PdfName("XObject"),
Subtype=PdfParser.PdfName("Image"),
Width=width, # * 72.0 / resolution,
Height=height, # * 72.0 / resolution,
Filter=PdfParser.PdfName(filter),
Filter=filter,
BitsPerComponent=bits,
Decode=decode,
DecodeParams=params,
DecodeParms=params,
ColorSpace=colorspace,
)