这是我放在一起的实用程序-仅在单个应用程序中进行了测试,因此不确定它的通用性,但应该是交钥匙的。在 python 3.9 中测试
def image2pdf(image: bytes or str, allow_lossy=True, **rgba_to_kwds) -> bytes:
"""
Converts an image to PDF, optionally allowing for lossy conversion.
:param image: if non RGBA image, this can be any valid input to img2pdf. If RGBA, then must be str (ie. path to image)
or bytes representation of image.
:param allow_lossy: if img2pdf.convert fails with AlphaChannelError, tries to downsample
:param rgba_to_kwds: kwds to _rgba_to
:return: bytes representation of PDF image. To save to disk
pdfBytes=image2pdf(someImage)
with open('converted.pdf', 'w') as f:
f.write(pdfBytes)
"""
try:
pdf_bytes = img2pdf.convert(image)
except img2pdf.AlphaChannelError as alphaError:
if allow_lossy:
rgbBytes = _rgba_to(image)
pdf_bytes = img2pdf.convert(rgbBytes, **rgba_to_kwds)
else:
raise alphaError
return pdf_bytes
def _rgba_to(image: bytes or str, to='RGB', intermediate='PNG') -> bytes:
logging.warning(f"Image has alpha channel... downsampling (newtype={to}, intermediate={intermediate}) and converting")
# Image is a filepath
if isinstance(image, str):
img = Image.open(image)
converted: Image = img.convert(to)
# Image is a bytestream
elif isinstance(image, bytes):
buffered = io.BytesIO(image)
img = Image.open(buffered)
converted: Image = img.convert(to)
else:
raise Exception(f"rgba downsampling only supported for images of type str (ie. filepath) or bytes - got {type(image)}")
buf = io.BytesIO()
converted.save(buf, format=intermediate)
byte_im = buf.getvalue()
return byte_im
def test_convert_png_image_with_alphachannel_to_pdf(): img_path = "some-rgba-image.png" pdf_bytes = image2pdf(img_path)
# Uncomment if want to view the pdf
with open('converted.pdf', "wb") as f:
f.write(pdf_bytes)