support file objects as input

main
josch 9 years ago
parent 18ca3b4491
commit 3fdd824201

@ -24,6 +24,10 @@ import struct
from PIL import Image from PIL import Image
from datetime import datetime from datetime import datetime
from jp2 import parsejp2 from jp2 import parsejp2
try:
from cStringIO import cStringIO
except ImportError:
from io import BytesIO as cStringIO
# XXX: Switch to use logging module. # XXX: Switch to use logging module.
def debug_out(message, verbose=True): def debug_out(message, verbose=True):
@ -214,85 +218,89 @@ def convert(images, dpi=None, x=None, y=None, title=None, author=None,
for imfilename in images: for imfilename in images:
debug_out("Reading %s"%imfilename, verbose) debug_out("Reading %s"%imfilename, verbose)
with open(imfilename, "rb") as im: try:
rawdata = im.read() rawdata = imfilename.read()
im.seek(0) im = cStringIO(rawdata)
try: except:
imgdata = Image.open(im) with open(imfilename, "rb") as im:
except IOError as e: rawdata = im.read()
# test if it is a jpeg2000 image im = cStringIO(rawdata)
if rawdata[:12] != "\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A": try:
error_out("cannot read input image (not jpeg2000)") imgdata = Image.open(im)
error_out("PIL: %s"%e) except IOError as e:
exit(1) # test if it is a jpeg2000 image
# image is jpeg2000 if rawdata[:12] != "\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A":
width, height, ics = parsejp2(rawdata) error_out("cannot read input image (not jpeg2000)")
imgformat = "JPEG2000" error_out("PIL: %s"%e)
exit(1)
if dpi: # image is jpeg2000
ndpi = dpi, dpi width, height, ics = parsejp2(rawdata)
debug_out("input dpi (forced) = %d x %d"%ndpi, verbose) imgformat = "JPEG2000"
else:
ndpi = (96, 96) # TODO: read real dpi if dpi:
debug_out("input dpi = %d x %d"%ndpi, verbose) ndpi = dpi, dpi
debug_out("input dpi (forced) = %d x %d"%ndpi, verbose)
if colorspace:
color = colorspace
debug_out("input colorspace (forced) = %s"%(ics))
else:
color = ics
debug_out("input colorspace = %s"%(ics), verbose)
else: else:
width, height = imgdata.size ndpi = (96, 96) # TODO: read real dpi
imgformat = imgdata.format debug_out("input dpi = %d x %d"%ndpi, verbose)
if dpi: if colorspace:
ndpi = dpi, dpi color = colorspace
debug_out("input dpi (forced) = %d x %d"%ndpi, verbose) debug_out("input colorspace (forced) = %s"%(ics))
else: else:
ndpi = imgdata.info.get("dpi", (96, 96)) color = ics
debug_out("input dpi = %d x %d"%ndpi, verbose) debug_out("input colorspace = %s"%(ics), verbose)
else:
if colorspace: width, height = imgdata.size
color = colorspace imgformat = imgdata.format
debug_out("input colorspace (forced) = %s"%(color), verbose)
else: if dpi:
color = imgdata.mode ndpi = dpi, dpi
if color == "CMYK" and imgformat == "JPEG": debug_out("input dpi (forced) = %d x %d"%ndpi, verbose)
# Adobe inverts CMYK JPEGs for some reason, and others else:
# have followed suit as well. Some software assumes the ndpi = imgdata.info.get("dpi", (96, 96))
# JPEG is inverted if the Adobe tag (APP14), while other debug_out("input dpi = %d x %d"%ndpi, verbose)
# software assumes all CMYK JPEGs are inverted. I don't
# have enough experience with these to know which is if colorspace:
# better for images currently in the wild, so I'm going color = colorspace
# with the first approach for now. debug_out("input colorspace (forced) = %s"%(color), verbose)
if "adobe" in imgdata.info: else:
color = "CMYK;I" color = imgdata.mode
debug_out("input colorspace = %s"%(color), verbose) if color == "CMYK" and imgformat == "JPEG":
# Adobe inverts CMYK JPEGs for some reason, and others
debug_out("width x height = %d x %d"%(width,height), verbose) # have followed suit as well. Some software assumes the
debug_out("imgformat = %s"%imgformat, verbose) # JPEG is inverted if the Adobe tag (APP14), while other
# software assumes all CMYK JPEGs are inverted. I don't
# depending on the input format, determine whether to pass the raw # have enough experience with these to know which is
# image or the zlib compressed color information # better for images currently in the wild, so I'm going
if imgformat is "JPEG" or imgformat is "JPEG2000": # with the first approach for now.
if color == '1': if "adobe" in imgdata.info:
error_out("jpeg can't be monochrome") color = "CMYK;I"
exit(1) debug_out("input colorspace = %s"%(color), verbose)
imgdata = rawdata
debug_out("width x height = %d x %d"%(width,height), verbose)
debug_out("imgformat = %s"%imgformat, verbose)
# depending on the input format, determine whether to pass the raw
# image or the zlib compressed color information
if imgformat is "JPEG" or imgformat is "JPEG2000":
if color == '1':
error_out("jpeg can't be monochrome")
exit(1)
imgdata = rawdata
else:
# because we do not support /CCITTFaxDecode
if color == '1':
debug_out("Converting colorspace 1 to L", verbose)
imgdata = imgdata.convert('L')
color = 'L'
elif color in ("RGB", "L", "CMYK", "CMYK;I"):
debug_out("Colorspace is OK: %s"%color, verbose)
else: else:
# because we do not support /CCITTFaxDecode debug_out("Converting colorspace %s to RGB"%color, verbose)
if color == '1': imgdata = imgdata.convert('RGB')
debug_out("Converting colorspace 1 to L", verbose) color = imgdata.mode
imgdata = imgdata.convert('L') imgdata = zlib.compress(imgdata.tostring())
color = 'L'
elif color in ("RGB", "L", "CMYK", "CMYK;I"):
debug_out("Colorspace is OK: %s"%color, verbose)
else:
debug_out("Converting colorspace %s to RGB"%color, verbose)
imgdata = imgdata.convert('RGB')
color = imgdata.mode
imgdata = zlib.compress(imgdata.tostring())
# pdf units = 1/72 inch # pdf units = 1/72 inch
if not x and not y: if not x and not y:

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

@ -1,20 +0,0 @@
import datetime
import os
import unittest
import img2pdf
HERE = os.path.dirname(__file__)
moddate = datetime.datetime(2014, 1, 1)
class TestImg2Pdf(unittest.TestCase):
def test_jpg2pdf(self):
with open(os.path.join(HERE, 'test.jpg'), 'r') as img_fp:
with open(os.path.join(HERE, 'test.pdf'), 'r') as pdf_fp:
self.assertEqual(
img2pdf.convert([img_fp], 150,
creationdate=moddate, moddate=moddate),
pdf_fp.read())
def test_png2pdf(self):
with open(os.path.join(HERE, 'test.png'), 'r') as img_fp:
self.assertRaises(SystemExit, img2pdf.convert, [img_fp], 150)
Loading…
Cancel
Save