release version 0.2.0 - big rewrite and lots of new features
- now Python3 only - pep8 compliant code - update my email to josch@mister-muffin.de - move from github to gitlab.mister-muffin.de/josch/img2pdf - use logging module - add extensive test suite - ability to read from standard input - pdf writer: - make more compatible with the interface of pdfrw module - print floats which equal to their integer conversion as integer - do not print trailing zeroes for floating point numbers - print more linebreaks - add binary string at beginning of PDF to indicate that the PDF contains binary data - handle datetime and unicode strings by using utf-16-be encoding - new options (see --help for more details): - --without-pdfrw - --imgsize - --border - --fit - --auto-orient - --viewer-panes - --viewer-initial-page - --viewer-magnification - --viewer-page-layout - --viewer-fit-window - --viewer-center-window - --viewer-fullscreen - remove short command line options for metadata arguments
This commit is contained in:
parent
02fad70e4b
commit
251238b410
10 changed files with 1973 additions and 685 deletions
36
CHANGES.rst
36
CHANGES.rst
|
@ -2,11 +2,38 @@
|
|||
CHANGES
|
||||
=======
|
||||
|
||||
0.1.6
|
||||
0.2.0
|
||||
-----
|
||||
|
||||
- replace -x and -y option by combined option -s (or --pagesize) and use -S
|
||||
for --subject
|
||||
- now Python3 only
|
||||
- pep8 compliant code
|
||||
- update my email to josch@mister-muffin.de
|
||||
- move from github to gitlab.mister-muffin.de/josch/img2pdf
|
||||
- use logging module
|
||||
- add extensive test suite
|
||||
- ability to read from standard input
|
||||
- pdf writer:
|
||||
- make more compatible with the interface of pdfrw module
|
||||
- print floats which equal to their integer conversion as integer
|
||||
- do not print trailing zeroes for floating point numbers
|
||||
- print more linebreaks
|
||||
- add binary string at beginning of PDF to indicate that the PDF
|
||||
contains binary data
|
||||
- handle datetime and unicode strings by using utf-16-be encoding
|
||||
- new options (see --help for more details):
|
||||
- --without-pdfrw
|
||||
- --imgsize
|
||||
- --border
|
||||
- --fit
|
||||
- --auto-orient
|
||||
- --viewer-panes
|
||||
- --viewer-initial-page
|
||||
- --viewer-magnification
|
||||
- --viewer-page-layout
|
||||
- --viewer-fit-window
|
||||
- --viewer-center-window
|
||||
- --viewer-fullscreen
|
||||
- remove short options for metadata command line arguments
|
||||
- correctly encode and escape non-ascii metadata
|
||||
- explicitly store date in UTC and allow parsing all date formats understood
|
||||
by dateutil and `date --date`
|
||||
|
@ -42,9 +69,6 @@ CHANGES
|
|||
------------------
|
||||
|
||||
- Initial PyPI release.
|
||||
|
||||
- Modified code to create proper package.
|
||||
|
||||
- Added tests.
|
||||
|
||||
- Added console script entry point.
|
||||
|
|
112
README.md
112
README.md
|
@ -1,31 +1,35 @@
|
|||
img2pdf
|
||||
=======
|
||||
|
||||
Losslessly convert images to PDF without unnecessarily re-encoding JPEG and
|
||||
JPEG2000 files. Image quality is retained without unnecessarily increasing
|
||||
file size.
|
||||
Losslessly convert raster images to PDF. The file size will not unnecessarily
|
||||
increase. One major application would be a number of scans made in JPEG format
|
||||
which should now become part of a single PDF document. Existing solutions
|
||||
would either re-encode the input JPEG files (leading to quality loss) or store
|
||||
them in the zip/flate format which results into the PDF becoming unnecessarily
|
||||
large in terms of its file size.
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
Quality loss can be avoided when converting JPEG and JPEG2000 images to
|
||||
PDF by embedding them without re-encoding. I wrote this piece of python code.
|
||||
because I was missing a tool to do this automatically.
|
||||
Quality loss can be avoided when converting JPEG and JPEG2000 images to PDF by
|
||||
embedding them without re-encoding. I wrote this piece of python code.
|
||||
because I was missing a tool to do this automatically. Img2pdf basically just
|
||||
wraps JPEG images into the PDF container as they are.
|
||||
|
||||
If you know how to embed JPEG and JPEG2000 images into a PDF container without
|
||||
recompression, using existing tools, please contact me so that I can put this
|
||||
code into the garbage bin :D
|
||||
If you know an existing tool which allows one to embed JPEG and JPEG2000 images
|
||||
into a PDF container without recompression, please contact me so that I can put
|
||||
this code into the garbage bin.
|
||||
|
||||
Functionality
|
||||
-------------
|
||||
|
||||
This program will take a list of images and produce a PDF file with the images
|
||||
embedded in it. JPEG and JPEG2000 images will be included without
|
||||
recompression. Images in other formats will be included with zip/flate
|
||||
recompression. Raster images in other formats will be included with zip/flate
|
||||
encoding which usually leads to an increase in the resulting size because
|
||||
formats like png compress better than PDF which just zip/flate compresses the
|
||||
RGB data. As a result, this tool is able to losslessly wrap images into a PDF
|
||||
container with a quality-filesize ratio that is typically better (in case of
|
||||
container with a quality to filesize ratio that is typically better (in case of
|
||||
JPEG and JPEG2000 images) or equal (in case of other formats) than that of
|
||||
existing tools.
|
||||
|
||||
|
@ -50,75 +54,26 @@ than the input JPEG or JPEG2000 file.
|
|||
|
||||
img2pdf is able to losslessly embed JPEG and JPEG2000 files into a PDF
|
||||
container without additional overhead (aside from the PDF structure itself),
|
||||
save other graphics formats using lossless zip compression,
|
||||
and produce multi-page PDF files when more than one input image is given.
|
||||
|
||||
Also, since JPEG and JPEG2000 images are not reencoded, conversion with
|
||||
img2pdf is several times faster than with other tools.
|
||||
save other graphics formats using lossless zip compression, and produce
|
||||
multi-page PDF files when more than one input image is given.
|
||||
|
||||
Also, since JPEG and JPEG2000 images are not reencoded, conversion with img2pdf
|
||||
is several times faster than with other tools.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
#### General Notes
|
||||
The images must be provided as files because img2pdf needs to seek in the file
|
||||
descriptor.
|
||||
|
||||
The images must be provided as files because img2pdf needs to seek
|
||||
in the file descriptor. Input cannot be piped through stdin.
|
||||
If no output file is specified with the `-o`/`--output` option, output will be
|
||||
done to stdout.
|
||||
|
||||
If no output file is specified with the `-o`/`--output` option,
|
||||
output will be to stdout.
|
||||
|
||||
Descriptions of the options should be self explanatory.
|
||||
They are available by running:
|
||||
The detailed documentation can be accessed by running:
|
||||
|
||||
img2pdf --help
|
||||
|
||||
|
||||
#### Controlling Page Size
|
||||
|
||||
The PDF page size can be manipulated. By default, the image will be sized "into" the given dimensions with the aspect ratio retained. For instance, to size an image into a page that is at most 500pt x 500pt, use:
|
||||
|
||||
img2pdf -s 500x500 -o output.pdf input.jpg
|
||||
|
||||
To "fill" out a page that is at least 500pt x 500pt, follow the dimensions with a `^`:
|
||||
|
||||
img2pdf -s 500x500^ -o output.pdf input.jpg
|
||||
|
||||
To output pages that are exactly 500pt x 500pt, follow the dimensions with an `!`:
|
||||
|
||||
img2pdf -s 500x500\! -o output.pdf input.jpg
|
||||
|
||||
Notice that the default unit is points. Units may be also be specified and mixed:
|
||||
|
||||
img2pdf -s 8.5inx27.94cm -o output.pdf input.jpg
|
||||
|
||||
If either width or height is omitted, the other will be calculated
|
||||
to preserve aspect ratio.
|
||||
|
||||
img2pdf -s x280mm -o output1.pdf input.jpg
|
||||
img2pdf -s 280mmx -o output2.pdf input.jpg
|
||||
|
||||
Some standard page sizes are recognized:
|
||||
|
||||
img2pdf -s letter -o output1.pdf input.jpg
|
||||
img2pdf -s a4 -o output2.pdf input.jpg
|
||||
|
||||
#### Colorspace
|
||||
|
||||
Currently, the colorspace must be forced for JPEG 2000 images that are
|
||||
not in the RGB colorspace. Available colorspace options are based on
|
||||
Python Imaging Library (PIL) short handles.
|
||||
|
||||
* `RGB` = RGB color
|
||||
* `L` = Grayscale
|
||||
* `1` = Black and white (internally converted to grayscale)
|
||||
* `CMYK` = CMYK color
|
||||
* `CMYK;I` = CMYK color with inversion
|
||||
|
||||
For example, to encode a grayscale JPEG2000 image, use:
|
||||
|
||||
img2pdf -C L -o output.pdf input.jp2
|
||||
|
||||
Bugs
|
||||
----
|
||||
|
||||
|
@ -135,20 +90,17 @@ outperformed by another lossless compression method, contact me.
|
|||
|
||||
I have not yet figured out how to determine the colorspace of JPEG2000 files.
|
||||
Therefore JPEG2000 files use DeviceRGB by default. For JPEG2000 files with
|
||||
other colorspaces, you must force it using the `--colorspace` option.
|
||||
other colorspaces, you must explicitly specify it using the `--colorspace`
|
||||
option.
|
||||
|
||||
It might be possible to store transparency using masks but it is not clear
|
||||
what the utility of such a functionality would be.
|
||||
|
||||
Most vector graphic formats can be losslessly turned into PDF (minus some of
|
||||
the features unsupported by PDF) but img2pdf will currently turn vector
|
||||
graphics into their lossy raster representations.
|
||||
|
||||
Acrobat is able to store a hint for the PDF reader of how to present the PDF
|
||||
when opening it. Things like automatic fullscreen or the zoom level can be
|
||||
configured.
|
||||
|
||||
It would be nice if a single input image could be read from standard input.
|
||||
graphics into their lossy raster representations. For converting raster
|
||||
graphics to PDF, use another tool like inkscape and then join the resulting
|
||||
pages with a tool like pdftk.
|
||||
|
||||
A configuration file could be used for default options.
|
||||
|
||||
|
@ -158,10 +110,6 @@ Installation
|
|||
On a Debian- and Ubuntu-based systems, dependencies may be installed
|
||||
with the following command:
|
||||
|
||||
apt-get install python python-pil python-setuptools
|
||||
|
||||
Or for Python 3:
|
||||
|
||||
apt-get install python3 python3-pil python3-setuptools
|
||||
|
||||
You can then install the package using:
|
||||
|
@ -187,7 +135,7 @@ You can then test the converter using:
|
|||
The package can also be used as a library:
|
||||
|
||||
import img2pdf
|
||||
pdf_bytes = img2pdf.convert(['test.jpg'])
|
||||
pdf_bytes = img2pdf.convert('test.jpg')
|
||||
|
||||
file = open("name.pdf","wb")
|
||||
file.write(pdf_bytes)
|
||||
|
|
40
setup.py
40
setup.py
|
@ -1,37 +1,37 @@
|
|||
from setuptools import setup
|
||||
|
||||
VERSION="0.1.6~git"
|
||||
VERSION = "0.2"
|
||||
|
||||
setup (
|
||||
setup(
|
||||
name='img2pdf',
|
||||
version=VERSION,
|
||||
author = "Johannes 'josch' Schauer",
|
||||
author_email = 'j.schauer@email.de',
|
||||
description = "Convert images to PDF via direct JPEG inclusion.",
|
||||
long_description = open('README.md').read(),
|
||||
license = "LGPL",
|
||||
keywords = "jpeg pdf converter",
|
||||
classifiers = [
|
||||
'Development Status :: 4 - Beta',
|
||||
author="Johannes 'josch' Schauer",
|
||||
author_email='josch@mister-muffin.de',
|
||||
description="Convert images to PDF via direct JPEG inclusion.",
|
||||
long_description=open('README.md').read(),
|
||||
license="LGPL",
|
||||
keywords="jpeg pdf converter",
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'Intended Audience :: Other Audience',
|
||||
'Environment :: Console',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)',
|
||||
'Programming Language :: Python',
|
||||
'License :: OSI Approved :: GNU Lesser General Public License v3 '
|
||||
'(LGPLv3)',
|
||||
'Natural Language :: English',
|
||||
'Operating System :: OS Independent'],
|
||||
url = 'https://github.com/josch/img2pdf',
|
||||
download_url = 'https://github.com/josch/img2pdf/archive/'+VERSION+'.tar.gz',
|
||||
url='https://gitlab.mister-muffin.de/josch/img2pdf',
|
||||
download_url='https://gitlab.mister-muffin.de/josch/img2pdf/repository/'
|
||||
'archive.tar.gz?ref=' + VERSION,
|
||||
package_dir={"": "src"},
|
||||
py_modules=['img2pdf', 'jp2'],
|
||||
include_package_data = True,
|
||||
test_suite = 'tests.test_suite',
|
||||
zip_safe = True,
|
||||
include_package_data=True,
|
||||
test_suite='tests.test_suite',
|
||||
zip_safe=True,
|
||||
install_requires=(
|
||||
'Pillow',
|
||||
),
|
||||
|
|
1874
src/img2pdf.py
1874
src/img2pdf.py
File diff suppressed because it is too large
Load diff
32
src/jp2.py
32
src/jp2.py
|
@ -21,6 +21,7 @@
|
|||
|
||||
import struct
|
||||
|
||||
|
||||
def getBox(data, byteStart, noBytes):
|
||||
boxLengthValue = struct.unpack(">I", data[byteStart:byteStart+4])[0]
|
||||
boxType = data[byteStart+4:byteStart+8]
|
||||
|
@ -34,11 +35,13 @@ def getBox(data, byteStart, noBytes):
|
|||
boxContents = data[byteStart+contentsStartOffset:byteEnd]
|
||||
return (boxLengthValue, boxType, byteEnd, boxContents)
|
||||
|
||||
|
||||
def parse_ihdr(data):
|
||||
height = struct.unpack(">I", data[0:4])[0]
|
||||
width = struct.unpack(">I", data[4:8])[0]
|
||||
return width, height
|
||||
|
||||
|
||||
def parse_colr(data):
|
||||
meth = struct.unpack(">B", data[0:1])[0]
|
||||
if meth != 1:
|
||||
|
@ -49,15 +52,18 @@ def parse_colr(data):
|
|||
elif enumCS == 17:
|
||||
return "L"
|
||||
else:
|
||||
raise Exception("only sRGB and greyscale color space is supported, got %d"%enumCS)
|
||||
raise Exception("only sRGB and greyscale color space is supported, "
|
||||
"got %d" % enumCS)
|
||||
|
||||
|
||||
def parse_jp2h(data):
|
||||
width, height, colorspace = None, None, None
|
||||
noBytes=len(data)
|
||||
byteStart=0
|
||||
boxLengthValue=1 # dummy value for while loop condition
|
||||
noBytes = len(data)
|
||||
byteStart = 0
|
||||
boxLengthValue = 1 # dummy value for while loop condition
|
||||
while byteStart < noBytes and boxLengthValue != 0:
|
||||
boxLengthValue, boxType, byteEnd, boxContents = getBox(data, byteStart, noBytes)
|
||||
boxLengthValue, boxType, byteEnd, boxContents = \
|
||||
getBox(data, byteStart, noBytes)
|
||||
if boxType == 'ihdr':
|
||||
width, height = parse_ihdr(boxContents)
|
||||
elif boxType == 'colr':
|
||||
|
@ -65,12 +71,14 @@ def parse_jp2h(data):
|
|||
byteStart = byteEnd
|
||||
return (width, height, colorspace)
|
||||
|
||||
|
||||
def parsejp2(data):
|
||||
noBytes=len(data)
|
||||
byteStart=0
|
||||
boxLengthValue=1 # dummy value for while loop condition
|
||||
noBytes = len(data)
|
||||
byteStart = 0
|
||||
boxLengthValue = 1 # dummy value for while loop condition
|
||||
while byteStart < noBytes and boxLengthValue != 0:
|
||||
boxLengthValue, boxType, byteEnd, boxContents = getBox(data, byteStart, noBytes)
|
||||
boxLengthValue, boxType, byteEnd, boxContents = \
|
||||
getBox(data, byteStart, noBytes)
|
||||
if boxType == 'jp2h':
|
||||
width, height, colorspace = parse_jp2h(boxContents)
|
||||
byteStart = byteEnd
|
||||
|
@ -85,6 +93,6 @@ def parsejp2(data):
|
|||
if __name__ == "__main__":
|
||||
import sys
|
||||
width, height, colorspace = parsejp2(open(sys.argv[1]).read())
|
||||
sys.stdout.write("width = %d"%width)
|
||||
sys.stdout.write("height = %d"%height)
|
||||
sys.stdout.write("colorspace = %s"%colorspace)
|
||||
sys.stdout.write("width = %d" % width)
|
||||
sys.stdout.write("height = %d" % height)
|
||||
sys.stdout.write("colorspace = %s" % colorspace)
|
||||
|
|
|
@ -7,102 +7,550 @@ from PIL import Image
|
|||
|
||||
HERE = os.path.dirname(__file__)
|
||||
|
||||
#convert +set date:create +set date:modify -define png:exclude-chunk=time
|
||||
# convert +set date:create +set date:modify -define png:exclude-chunk=time
|
||||
|
||||
# we define some variables so that the table below can be narrower
|
||||
psl = (972, 504) # --pagesize landscape
|
||||
psp = (504, 972) # --pagesize portrait
|
||||
isl = (756, 324) # --imgsize landscape
|
||||
isp = (324, 756) # --imgsize portrait
|
||||
border = (162, 270) # --border
|
||||
# there is no need to have test cases with the same images with inverted
|
||||
# orientation (landscape/portrait) because --pagesize and --imgsize are
|
||||
# already inverted
|
||||
im1 = (864, 288) # imgpx #1 => 648x216
|
||||
im2 = (1152, 576) # imgpx #2 => 864x432
|
||||
# shortcuts for fit modes
|
||||
f_into = img2pdf.FitMode.into
|
||||
f_fill = img2pdf.FitMode.fill
|
||||
f_exact = img2pdf.FitMode.exact
|
||||
f_shrink = img2pdf.FitMode.shrink
|
||||
f_enlarge = img2pdf.FitMode.enlarge
|
||||
layout_test_cases = [
|
||||
# psp=972x504, psl=504x972, isl=756x324, isp=324x756, border=162:270
|
||||
# --pagesize --border -a pagepdf imgpdf
|
||||
# --imgsize --fit
|
||||
(None, None, None, f_into, 0, (648, 216), (648, 216), # 000
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, None, f_into, 1, (648, 216), (648, 216), # 001
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, None, f_fill, 0, (648, 216), (648, 216), # 002
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, None, f_fill, 1, (648, 216), (648, 216), # 003
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, None, f_exact, 0, (648, 216), (648, 216), # 004
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, None, f_exact, 1, (648, 216), (648, 216), # 005
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, None, f_shrink, 0, (648, 216), (648, 216), # 006
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, None, f_shrink, 1, (648, 216), (648, 216), # 007
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, None, f_enlarge, 0, (648, 216), (648, 216), # 008
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, None, f_enlarge, 1, (648, 216), (648, 216), # 009
|
||||
(864, 432), (864, 432)),
|
||||
(None, None, border, f_into, 0, (1188, 540), (648, 216), # 010
|
||||
(1404, 756), (864, 432)),
|
||||
(None, None, border, f_into, 1, (1188, 540), (648, 216), # 011
|
||||
(1404, 756), (864, 432)),
|
||||
(None, None, border, f_fill, 0, (1188, 540), (648, 216), # 012
|
||||
(1404, 756), (864, 432)),
|
||||
(None, None, border, f_fill, 1, (1188, 540), (648, 216), # 013
|
||||
(1404, 756), (864, 432)),
|
||||
(None, None, border, f_exact, 0, (1188, 540), (648, 216), # 014
|
||||
(1404, 756), (864, 432)),
|
||||
(None, None, border, f_exact, 1, (1188, 540), (648, 216), # 015
|
||||
(1404, 756), (864, 432)),
|
||||
(None, None, border, f_shrink, 0, (1188, 540), (648, 216), # 016
|
||||
(1404, 756), (864, 432)),
|
||||
(None, None, border, f_shrink, 1, (1188, 540), (648, 216), # 017
|
||||
(1404, 756), (864, 432)),
|
||||
(None, None, border, f_enlarge, 0, (1188, 540), (648, 216), # 018
|
||||
(1404, 756), (864, 432)),
|
||||
(None, None, border, f_enlarge, 1, (1188, 540), (648, 216), # 019
|
||||
(1404, 756), (864, 432)),
|
||||
(None, isp, None, f_into, 0, (324, 108), (324, 108), # 020
|
||||
(324, 162), (324, 162)),
|
||||
(None, isp, None, f_into, 1, (324, 108), (324, 108), # 021
|
||||
(324, 162), (324, 162)),
|
||||
(None, isp, None, f_fill, 0, (2268, 756), (2268, 756), # 022
|
||||
(1512, 756), (1512, 756)),
|
||||
(None, isp, None, f_fill, 1, (2268, 756), (2268, 756), # 023
|
||||
(1512, 756), (1512, 756)),
|
||||
(None, isp, None, f_exact, 0, (324, 756), (324, 756), # 024
|
||||
(324, 756), (324, 756)),
|
||||
(None, isp, None, f_exact, 1, (324, 756), (324, 756), # 025
|
||||
(324, 756), (324, 756)),
|
||||
(None, isp, None, f_shrink, 0, (324, 108), (324, 108), # 026
|
||||
(324, 162), (324, 162)),
|
||||
(None, isp, None, f_shrink, 1, (324, 108), (324, 108), # 027
|
||||
(324, 162), (324, 162)),
|
||||
(None, isp, None, f_enlarge, 0, (648, 216), (648, 216), # 028
|
||||
(864, 432), (864, 432)),
|
||||
(None, isp, None, f_enlarge, 1, (648, 216), (648, 216), # 029
|
||||
(864, 432), (864, 432)),
|
||||
(None, isp, border, f_into, 0, (864, 432), (324, 108), # 030
|
||||
(864, 486), (324, 162)),
|
||||
(None, isp, border, f_into, 1, (864, 432), (324, 108), # 031
|
||||
(864, 486), (324, 162)),
|
||||
(None, isp, border, f_fill, 0, (2808, 1080), (2268, 756), # 032
|
||||
(2052, 1080), (1512, 756)),
|
||||
(None, isp, border, f_fill, 1, (2808, 1080), (2268, 756), # 033
|
||||
(2052, 1080), (1512, 756)),
|
||||
(None, isp, border, f_exact, 0, (864, 1080), (324, 756), # 034
|
||||
(864, 1080), (324, 756)),
|
||||
(None, isp, border, f_exact, 1, (864, 1080), (324, 756), # 035
|
||||
(864, 1080), (324, 756)),
|
||||
(None, isp, border, f_shrink, 0, (864, 432), (324, 108), # 036
|
||||
(864, 486), (324, 162)),
|
||||
(None, isp, border, f_shrink, 1, (864, 432), (324, 108), # 037
|
||||
(864, 486), (324, 162)),
|
||||
(None, isp, border, f_enlarge, 0, (1188, 540), (648, 216), # 038
|
||||
(1404, 756), (864, 432)),
|
||||
(None, isp, border, f_enlarge, 1, (1188, 540), (648, 216), # 039
|
||||
(1404, 756), (864, 432)),
|
||||
(None, isl, None, f_into, 0, (756, 252), (756, 252), # 040
|
||||
(648, 324), (648, 324)),
|
||||
(None, isl, None, f_into, 1, (756, 252), (756, 252), # 041
|
||||
(648, 324), (648, 324)),
|
||||
(None, isl, None, f_fill, 0, (972, 324), (972, 324), # 042
|
||||
(756, 378), (756, 378)),
|
||||
(None, isl, None, f_fill, 1, (972, 324), (972, 324), # 043
|
||||
(756, 378), (756, 378)),
|
||||
(None, isl, None, f_exact, 0, (756, 324), (756, 324), # 044
|
||||
(756, 324), (756, 324)),
|
||||
(None, isl, None, f_exact, 1, (756, 324), (756, 324), # 045
|
||||
(756, 324), (756, 324)),
|
||||
(None, isl, None, f_shrink, 0, (648, 216), (648, 216), # 046
|
||||
(648, 324), (648, 324)),
|
||||
(None, isl, None, f_shrink, 1, (648, 216), (648, 216), # 047
|
||||
(648, 324), (648, 324)),
|
||||
(None, isl, None, f_enlarge, 0, (756, 252), (756, 252), # 048
|
||||
(864, 432), (864, 432)),
|
||||
(None, isl, None, f_enlarge, 1, (756, 252), (756, 252), # 049
|
||||
(864, 432), (864, 432)),
|
||||
# psp=972x504, psp=504x972, isl=756x324, isp=324x756, border=162:270
|
||||
# --pagesize --border -a pagepdf imgpdf
|
||||
# --imgsize --fit imgpx
|
||||
(None, isl, border, f_into, 0, (1296, 576), (756, 252), # 050
|
||||
(1188, 648), (648, 324)),
|
||||
(None, isl, border, f_into, 1, (1296, 576), (756, 252), # 051
|
||||
(1188, 648), (648, 324)),
|
||||
(None, isl, border, f_fill, 0, (1512, 648), (972, 324), # 052
|
||||
(1296, 702), (756, 378)),
|
||||
(None, isl, border, f_fill, 1, (1512, 648), (972, 324), # 053
|
||||
(1296, 702), (756, 378)),
|
||||
(None, isl, border, f_exact, 0, (1296, 648), (756, 324), # 054
|
||||
(1296, 648), (756, 324)),
|
||||
(None, isl, border, f_exact, 1, (1296, 648), (756, 324), # 055
|
||||
(1296, 648), (756, 324)),
|
||||
(None, isl, border, f_shrink, 0, (1188, 540), (648, 216), # 056
|
||||
(1188, 648), (648, 324)),
|
||||
(None, isl, border, f_shrink, 1, (1188, 540), (648, 216), # 057
|
||||
(1188, 648), (648, 324)),
|
||||
(None, isl, border, f_enlarge, 0, (1296, 576), (756, 252), # 058
|
||||
(1404, 756), (864, 432)),
|
||||
(None, isl, border, f_enlarge, 1, (1296, 576), (756, 252), # 059
|
||||
(1404, 756), (864, 432)),
|
||||
(psp, None, None, f_into, 0, (504, 972), (504, 168), # 060
|
||||
(504, 972), (504, 252)),
|
||||
(psp, None, None, f_into, 1, (972, 504), (972, 324), # 061
|
||||
(972, 504), (972, 486)),
|
||||
(psp, None, None, f_fill, 0, (504, 972), (2916, 972), # 062
|
||||
(504, 972), (1944, 972)),
|
||||
(psp, None, None, f_fill, 1, (972, 504), (1512, 504), # 063
|
||||
(972, 504), (1008, 504)),
|
||||
(psp, None, None, f_exact, 0, (504, 972), (504, 972), # 064
|
||||
(504, 972), (504, 972)),
|
||||
(psp, None, None, f_exact, 1, (972, 504), (972, 504), # 065
|
||||
(972, 504), (972, 504)),
|
||||
(psp, None, None, f_shrink, 0, (504, 972), (504, 168), # 066
|
||||
(504, 972), (504, 252)),
|
||||
(psp, None, None, f_shrink, 1, (972, 504), (648, 216), # 067
|
||||
(972, 504), (864, 432)),
|
||||
(psp, None, None, f_enlarge, 0, (504, 972), (648, 216), # 068
|
||||
(504, 972), (864, 432)),
|
||||
(psp, None, None, f_enlarge, 1, (972, 504), (972, 324), # 069
|
||||
(972, 504), (972, 486)),
|
||||
(psp, None, border, f_into, 0, (504, 972), (180, 60), # 070
|
||||
(504, 972), (180, 90)),
|
||||
(psp, None, border, f_into, 1, (972, 504), (432, 144), # 071
|
||||
(972, 504), (360, 180)),
|
||||
(psp, None, border, f_fill, 0, (504, 972), (1296, 432), # 072
|
||||
(504, 972), (864, 432)),
|
||||
(psp, None, border, f_fill, 1, (972, 504), (540, 180), # 073
|
||||
(972, 504), (432, 216)),
|
||||
(psp, None, border, f_exact, 0, (504, 972), (180, 432), # 074
|
||||
(504, 972), (180, 432)),
|
||||
(psp, None, border, f_exact, 1, (972, 504), (432, 180), # 075
|
||||
(972, 504), (432, 180)),
|
||||
(psp, None, border, f_shrink, 0, (504, 972), (180, 60), # 076
|
||||
(504, 972), (180, 90)),
|
||||
(psp, None, border, f_shrink, 1, (972, 504), (432, 144), # 077
|
||||
(972, 504), (360, 180)),
|
||||
(psp, None, border, f_enlarge, 0, (504, 972), (648, 216), # 078
|
||||
(504, 972), (864, 432)),
|
||||
(psp, None, border, f_enlarge, 1, (972, 504), (648, 216), # 079
|
||||
(972, 504), (864, 432)),
|
||||
(psp, isp, None, f_into, 0, (504, 972), (324, 108), # 080
|
||||
(504, 972), (324, 162)),
|
||||
(psp, isp, None, f_into, 1, (972, 504), (324, 108), # 081
|
||||
(972, 504), (324, 162)),
|
||||
(psp, isp, None, f_fill, 0, (504, 972), (2268, 756), # 082
|
||||
(504, 972), (1512, 756)),
|
||||
(psp, isp, None, f_fill, 1, (972, 504), (2268, 756), # 083
|
||||
(972, 504), (1512, 756)),
|
||||
(psp, isp, None, f_exact, 0, (504, 972), (324, 756), # 084
|
||||
(504, 972), (324, 756)),
|
||||
(psp, isp, None, f_exact, 1, (972, 504), (324, 756), # 085
|
||||
(972, 504), (324, 756)),
|
||||
(psp, isp, None, f_shrink, 0, (504, 972), (324, 108), # 086
|
||||
(504, 972), (324, 162)),
|
||||
(psp, isp, None, f_shrink, 1, (972, 504), (324, 108), # 087
|
||||
(972, 504), (324, 162)),
|
||||
(psp, isp, None, f_enlarge, 0, (504, 972), (648, 216), # 088
|
||||
(504, 972), (864, 432)),
|
||||
(psp, isp, None, f_enlarge, 1, (972, 504), (648, 216), # 089
|
||||
(972, 504), (864, 432)),
|
||||
(psp, isp, border, f_into, 0, (504, 972), (324, 108), # 090
|
||||
(504, 972), (324, 162)),
|
||||
(psp, isp, border, f_into, 1, (972, 504), (324, 108), # 091
|
||||
(972, 504), (324, 162)),
|
||||
(psp, isp, border, f_fill, 0, (504, 972), (2268, 756), # 092
|
||||
(504, 972), (1512, 756)),
|
||||
(psp, isp, border, f_fill, 1, (972, 504), (2268, 756), # 093
|
||||
(972, 504), (1512, 756)),
|
||||
(psp, isp, border, f_exact, 0, (504, 972), (324, 756), # 094
|
||||
(504, 972), (324, 756)),
|
||||
(psp, isp, border, f_exact, 1, (972, 504), (324, 756), # 095
|
||||
(972, 504), (324, 756)),
|
||||
(psp, isp, border, f_shrink, 0, (504, 972), (324, 108), # 096
|
||||
(504, 972), (324, 162)),
|
||||
(psp, isp, border, f_shrink, 1, (972, 504), (324, 108), # 097
|
||||
(972, 504), (324, 162)),
|
||||
(psp, isp, border, f_enlarge, 0, (504, 972), (648, 216), # 098
|
||||
(504, 972), (864, 432)),
|
||||
(psp, isp, border, f_enlarge, 1, (972, 504), (648, 216), # 099
|
||||
(972, 504), (864, 432)),
|
||||
# psp=972x504, psp=504x972, isl=756x324, isp=324x756, border=162:270
|
||||
# --pagesize --border -a pagepdf imgpdf
|
||||
# --imgsize --fit imgpx
|
||||
(psp, isl, None, f_into, 0, (504, 972), (756, 252), # 100
|
||||
(504, 972), (648, 324)),
|
||||
(psp, isl, None, f_into, 1, (972, 504), (756, 252), # 101
|
||||
(972, 504), (648, 324)),
|
||||
(psp, isl, None, f_fill, 0, (504, 972), (972, 324), # 102
|
||||
(504, 972), (756, 378)),
|
||||
(psp, isl, None, f_fill, 1, (972, 504), (972, 324), # 103
|
||||
(972, 504), (756, 378)),
|
||||
(psp, isl, None, f_exact, 0, (504, 972), (756, 324), # 104
|
||||
(504, 972), (756, 324)),
|
||||
(psp, isl, None, f_exact, 1, (972, 504), (756, 324), # 105
|
||||
(972, 504), (756, 324)),
|
||||
(psp, isl, None, f_shrink, 0, (504, 972), (648, 216), # 106
|
||||
(504, 972), (648, 324)),
|
||||
(psp, isl, None, f_shrink, 1, (972, 504), (648, 216), # 107
|
||||
(972, 504), (648, 324)),
|
||||
(psp, isl, None, f_enlarge, 0, (504, 972), (756, 252), # 108
|
||||
(504, 972), (864, 432)),
|
||||
(psp, isl, None, f_enlarge, 1, (972, 504), (756, 252), # 109
|
||||
(972, 504), (864, 432)),
|
||||
(psp, isl, border, f_into, 0, (504, 972), (756, 252), # 110
|
||||
(504, 972), (648, 324)),
|
||||
(psp, isl, border, f_into, 1, (972, 504), (756, 252), # 111
|
||||
(972, 504), (648, 324)),
|
||||
(psp, isl, border, f_fill, 0, (504, 972), (972, 324), # 112
|
||||
(504, 972), (756, 378)),
|
||||
(psp, isl, border, f_fill, 1, (972, 504), (972, 324), # 113
|
||||
(972, 504), (756, 378)),
|
||||
(psp, isl, border, f_exact, 0, (504, 972), (756, 324), # 114
|
||||
(504, 972), (756, 324)),
|
||||
(psp, isl, border, f_exact, 1, (972, 504), (756, 324), # 115
|
||||
(972, 504), (756, 324)),
|
||||
(psp, isl, border, f_shrink, 0, (504, 972), (648, 216), # 116
|
||||
(504, 972), (648, 324)),
|
||||
(psp, isl, border, f_shrink, 1, (972, 504), (648, 216), # 117
|
||||
(972, 504), (648, 324)),
|
||||
(psp, isl, border, f_enlarge, 0, (504, 972), (756, 252), # 118
|
||||
(504, 972), (864, 432)),
|
||||
(psp, isl, border, f_enlarge, 1, (972, 504), (756, 252), # 119
|
||||
(972, 504), (864, 432)),
|
||||
(psl, None, None, f_into, 0, (972, 504), (972, 324), # 120
|
||||
(972, 504), (972, 486)),
|
||||
(psl, None, None, f_into, 1, (972, 504), (972, 324), # 121
|
||||
(972, 504), (972, 486)),
|
||||
(psl, None, None, f_fill, 0, (972, 504), (1512, 504), # 122
|
||||
(972, 504), (1008, 504)),
|
||||
(psl, None, None, f_fill, 1, (972, 504), (1512, 504), # 123
|
||||
(972, 504), (1008, 504)),
|
||||
(psl, None, None, f_exact, 0, (972, 504), (972, 504), # 124
|
||||
(972, 504), (972, 504)),
|
||||
(psl, None, None, f_exact, 1, (972, 504), (972, 504), # 125
|
||||
(972, 504), (972, 504)),
|
||||
(psl, None, None, f_shrink, 0, (972, 504), (648, 216), # 126
|
||||
(972, 504), (864, 432)),
|
||||
(psl, None, None, f_shrink, 1, (972, 504), (648, 216), # 127
|
||||
(972, 504), (864, 432)),
|
||||
(psl, None, None, f_enlarge, 0, (972, 504), (972, 324), # 128
|
||||
(972, 504), (972, 486)),
|
||||
(psl, None, None, f_enlarge, 1, (972, 504), (972, 324), # 129
|
||||
(972, 504), (972, 486)),
|
||||
(psl, None, border, f_into, 0, None, None, None, None), # 130
|
||||
(psl, None, border, f_into, 1, None, None, None, None), # 131
|
||||
(psl, None, border, f_fill, 0, (972, 504), (648, 216), # 132
|
||||
(972, 504), (648, 324)),
|
||||
(psl, None, border, f_fill, 1, (972, 504), (648, 216), # 133
|
||||
(972, 504), (648, 324)),
|
||||
(psl, None, border, f_exact, 0, None, None, None, None), # 134
|
||||
(psl, None, border, f_exact, 1, None, None, None, None), # 135
|
||||
(psl, None, border, f_shrink, 0, None, None, None, None), # 136
|
||||
(psl, None, border, f_shrink, 1, None, None, None, None), # 137
|
||||
(psl, None, border, f_enlarge, 0, (972, 504), (648, 216), # 138
|
||||
(972, 504), (864, 432)),
|
||||
(psl, None, border, f_enlarge, 1, (972, 504), (648, 216), # 139
|
||||
(972, 504), (864, 432)),
|
||||
(psl, isp, None, f_into, 0, (972, 504), (324, 108), # 140
|
||||
(972, 504), (324, 162)),
|
||||
(psl, isp, None, f_into, 1, (972, 504), (324, 108), # 141
|
||||
(972, 504), (324, 162)),
|
||||
(psl, isp, None, f_fill, 0, (972, 504), (2268, 756), # 142
|
||||
(972, 504), (1512, 756)),
|
||||
(psl, isp, None, f_fill, 1, (972, 504), (2268, 756), # 143
|
||||
(972, 504), (1512, 756)),
|
||||
(psl, isp, None, f_exact, 0, (972, 504), (324, 756), # 144
|
||||
(972, 504), (324, 756)),
|
||||
(psl, isp, None, f_exact, 1, (972, 504), (324, 756), # 145
|
||||
(972, 504), (324, 756)),
|
||||
(psl, isp, None, f_shrink, 0, (972, 504), (324, 108), # 146
|
||||
(972, 504), (324, 162)),
|
||||
(psl, isp, None, f_shrink, 1, (972, 504), (324, 108), # 147
|
||||
(972, 504), (324, 162)),
|
||||
(psl, isp, None, f_enlarge, 0, (972, 504), (648, 216), # 148
|
||||
(972, 504), (864, 432)),
|
||||
(psl, isp, None, f_enlarge, 1, (972, 504), (648, 216), # 149
|
||||
(972, 504), (864, 432)),
|
||||
# psp=972x504, psl=504x972, isl=756x324, isp=324x756, border=162:270
|
||||
# --pagesize --border -a pagepdf imgpdf
|
||||
# --imgsize --fit imgpx
|
||||
(psl, isp, border, f_into, 0, (972, 504), (324, 108), # 150
|
||||
(972, 504), (324, 162)),
|
||||
(psl, isp, border, f_into, 1, (972, 504), (324, 108), # 151
|
||||
(972, 504), (324, 162)),
|
||||
(psl, isp, border, f_fill, 0, (972, 504), (2268, 756), # 152
|
||||
(972, 504), (1512, 756)),
|
||||
(psl, isp, border, f_fill, 1, (972, 504), (2268, 756), # 153
|
||||
(972, 504), (1512, 756)),
|
||||
(psl, isp, border, f_exact, 0, (972, 504), (324, 756), # 154
|
||||
(972, 504), (324, 756)),
|
||||
(psl, isp, border, f_exact, 1, (972, 504), (324, 756), # 155
|
||||
(972, 504), (324, 756)),
|
||||
(psl, isp, border, f_shrink, 0, (972, 504), (324, 108), # 156
|
||||
(972, 504), (324, 162)),
|
||||
(psl, isp, border, f_shrink, 1, (972, 504), (324, 108), # 157
|
||||
(972, 504), (324, 162)),
|
||||
(psl, isp, border, f_enlarge, 0, (972, 504), (648, 216), # 158
|
||||
(972, 504), (864, 432)),
|
||||
(psl, isp, border, f_enlarge, 1, (972, 504), (648, 216), # 159
|
||||
(972, 504), (864, 432)),
|
||||
(psl, isl, None, f_into, 0, (972, 504), (756, 252), # 160
|
||||
(972, 504), (648, 324)),
|
||||
(psl, isl, None, f_into, 1, (972, 504), (756, 252), # 161
|
||||
(972, 504), (648, 324)),
|
||||
(psl, isl, None, f_fill, 0, (972, 504), (972, 324), # 162
|
||||
(972, 504), (756, 378)),
|
||||
(psl, isl, None, f_fill, 1, (972, 504), (972, 324), # 163
|
||||
(972, 504), (756, 378)),
|
||||
(psl, isl, None, f_exact, 0, (972, 504), (756, 324), # 164
|
||||
(972, 504), (756, 324)),
|
||||
(psl, isl, None, f_exact, 1, (972, 504), (756, 324), # 165
|
||||
(972, 504), (756, 324)),
|
||||
(psl, isl, None, f_shrink, 0, (972, 504), (648, 216), # 166
|
||||
(972, 504), (648, 324)),
|
||||
(psl, isl, None, f_shrink, 1, (972, 504), (648, 216), # 167
|
||||
(972, 504), (648, 324)),
|
||||
(psl, isl, None, f_enlarge, 0, (972, 504), (756, 252), # 168
|
||||
(972, 504), (864, 432)),
|
||||
(psl, isl, None, f_enlarge, 1, (972, 504), (756, 252), # 169
|
||||
(972, 504), (864, 432)),
|
||||
(psl, isl, border, f_into, 0, (972, 504), (756, 252), # 170
|
||||
(972, 504), (648, 324)),
|
||||
(psl, isl, border, f_into, 1, (972, 504), (756, 252), # 171
|
||||
(972, 504), (648, 324)),
|
||||
(psl, isl, border, f_fill, 0, (972, 504), (972, 324), # 172
|
||||
(972, 504), (756, 378)),
|
||||
(psl, isl, border, f_fill, 1, (972, 504), (972, 324), # 173
|
||||
(972, 504), (756, 378)),
|
||||
(psl, isl, border, f_exact, 0, (972, 504), (756, 324), # 174
|
||||
(972, 504), (756, 324)),
|
||||
(psl, isl, border, f_exact, 1, (972, 504), (756, 324), # 175
|
||||
(972, 504), (756, 324)),
|
||||
(psl, isl, border, f_shrink, 0, (972, 504), (648, 216), # 176
|
||||
(972, 504), (648, 324)),
|
||||
(psl, isl, border, f_shrink, 1, (972, 504), (648, 216), # 177
|
||||
(972, 504), (648, 324)),
|
||||
(psl, isl, border, f_enlarge, 0, (972, 504), (756, 252), # 178
|
||||
(972, 504), (864, 432)),
|
||||
(psl, isl, border, f_enlarge, 1, (972, 504), (756, 252), # 179
|
||||
(972, 504), (864, 432)),
|
||||
]
|
||||
|
||||
|
||||
def test_suite():
|
||||
class TestImg2Pdf(unittest.TestCase):
|
||||
pass
|
||||
|
||||
for test_name in os.listdir(os.path.join(HERE, "input")):
|
||||
for i, (psopt, isopt, border, fit, ao, pspdf1, ispdf1,
|
||||
pspdf2, ispdf2) in enumerate(layout_test_cases):
|
||||
if isopt is not None:
|
||||
isopt = ((img2pdf.ImgSize.abs, isopt[0]),
|
||||
(img2pdf.ImgSize.abs, isopt[1]))
|
||||
|
||||
def layout_handler(
|
||||
self, psopt, isopt, border, fit, ao, pspdf, ispdf, im):
|
||||
layout_fun = img2pdf.get_layout_fun(psopt, isopt, border, fit, ao)
|
||||
try:
|
||||
pwpdf, phpdf, iwpdf, ihpdf = \
|
||||
layout_fun(im[0], im[1], (img2pdf.default_dpi,
|
||||
img2pdf.default_dpi))
|
||||
self.assertEqual((pwpdf, phpdf), pspdf)
|
||||
self.assertEqual((iwpdf, ihpdf), ispdf)
|
||||
except img2pdf.NegativeDimensionException:
|
||||
self.assertEqual(None, pspdf)
|
||||
self.assertEqual(None, ispdf)
|
||||
|
||||
def layout_handler_im1(self, psopt=psopt, isopt=isopt, border=border,
|
||||
fit=fit, ao=ao, pspdf=pspdf1, ispdf=ispdf1):
|
||||
layout_handler(self, psopt, isopt, border, fit, ao, pspdf, ispdf,
|
||||
im1)
|
||||
setattr(TestImg2Pdf, "test_layout_%03d_im1" % i, layout_handler_im1)
|
||||
|
||||
def layout_handler_im2(self, psopt=psopt, isopt=isopt, border=border,
|
||||
fit=fit, ao=ao, pspdf=pspdf2, ispdf=ispdf2):
|
||||
layout_handler(self, psopt, isopt, border, fit, ao, pspdf, ispdf,
|
||||
im2)
|
||||
setattr(TestImg2Pdf, "test_layout_%03d_im2" % i, layout_handler_im2)
|
||||
|
||||
files = os.listdir(os.path.join(HERE, "input"))
|
||||
for with_pdfrw, test_name in [(a, b) for a in [True, False]
|
||||
for b in files]:
|
||||
inputf = os.path.join(HERE, "input", test_name)
|
||||
if not os.path.isfile(inputf):
|
||||
continue
|
||||
outputf = os.path.join(HERE, "output", test_name+".pdf")
|
||||
assert os.path.isfile(outputf)
|
||||
def handle(self, f=inputf, out=outputf):
|
||||
|
||||
def handle(self, f=inputf, out=outputf, with_pdfrw=with_pdfrw):
|
||||
with open(f, "rb") as inf:
|
||||
orig_imgdata = inf.read()
|
||||
pdf = img2pdf.convert([f], nodate=True)
|
||||
imgdata = b""
|
||||
instream = False
|
||||
imgobj = False
|
||||
colorspace = None
|
||||
imgfilter = None
|
||||
width = None
|
||||
height = None
|
||||
length = None
|
||||
# ugly workaround to parse the created pdf
|
||||
for line in pdf.split(b'\n'):
|
||||
if instream:
|
||||
if line == b"endstream":
|
||||
break
|
||||
else:
|
||||
imgdata += line + b'\n'
|
||||
else:
|
||||
if imgobj and line == b"stream":
|
||||
instream = True
|
||||
elif b"/Subtype /Image" in line:
|
||||
imgobj = True
|
||||
elif b"/Width" in line:
|
||||
width = int(line.split()[-1])
|
||||
elif b"/Height" in line:
|
||||
height = int(line.split()[-1])
|
||||
elif b"/Length" in line:
|
||||
length = int(line.split()[-1])
|
||||
elif b"/Filter" in line:
|
||||
imgfilter = line.split()[-2]
|
||||
elif b"/ColorSpace" in line:
|
||||
colorspace = line.split()[-1]
|
||||
# remove trailing \n
|
||||
imgdata = imgdata[:-1]
|
||||
# test if the length field is correct
|
||||
self.assertEqual(len(imgdata), length)
|
||||
output = img2pdf.convert(orig_imgdata, nodate=True,
|
||||
with_pdfrw=with_pdfrw)
|
||||
from io import StringIO, BytesIO
|
||||
from pdfrw import PdfReader, PdfName, PdfWriter
|
||||
from pdfrw.py23_diffs import convert_load, convert_store
|
||||
x = PdfReader(StringIO(convert_load(output)))
|
||||
self.assertEqual(sorted(x.keys()), [PdfName.Info, PdfName.Root,
|
||||
PdfName.Size])
|
||||
self.assertEqual(x.Size, '7')
|
||||
self.assertEqual(x.Info, {})
|
||||
self.assertEqual(sorted(x.Root.keys()), [PdfName.Pages,
|
||||
PdfName.Type])
|
||||
self.assertEqual(x.Root.Type, PdfName.Catalog)
|
||||
self.assertEqual(sorted(x.Root.Pages.keys()),
|
||||
[PdfName.Count, PdfName.Kids, PdfName.Type])
|
||||
self.assertEqual(x.Root.Pages.Count, '1')
|
||||
self.assertEqual(x.Root.Pages.Type, PdfName.Pages)
|
||||
self.assertEqual(len(x.Root.Pages.Kids), 1)
|
||||
self.assertEqual(sorted(x.Root.Pages.Kids[0].keys()),
|
||||
[PdfName.Contents, PdfName.MediaBox,
|
||||
PdfName.Parent, PdfName.Resources, PdfName.Type])
|
||||
self.assertEqual(x.Root.Pages.Kids[0].MediaBox,
|
||||
['0', '0', '115', '48'])
|
||||
self.assertEqual(x.Root.Pages.Kids[0].Parent, x.Root.Pages)
|
||||
self.assertEqual(x.Root.Pages.Kids[0].Type, PdfName.Page)
|
||||
self.assertEqual(x.Root.Pages.Kids[0].Resources.keys(),
|
||||
[PdfName.XObject])
|
||||
self.assertEqual(x.Root.Pages.Kids[0].Resources.XObject.keys(),
|
||||
[PdfName.Im0])
|
||||
self.assertEqual(x.Root.Pages.Kids[0].Contents.keys(),
|
||||
[PdfName.Length])
|
||||
self.assertEqual(x.Root.Pages.Kids[0].Contents.Length,
|
||||
str(len(x.Root.Pages.Kids[0].Contents.stream)))
|
||||
self.assertEqual(x.Root.Pages.Kids[0].Contents.stream,
|
||||
"q\n115.0000 0 0 48.0000 0.0000 0.0000 cm\n/Im0 "
|
||||
"Do\nQ")
|
||||
|
||||
imgprops = x.Root.Pages.Kids[0].Resources.XObject.Im0
|
||||
|
||||
# test if the filter is valid:
|
||||
self.assertIn(imgfilter, [b"/DCTDecode", b"/JPXDecode", b"/FlateDecode"])
|
||||
self.assertIn(
|
||||
imgprops.Filter, [[PdfName.DCTDecode], [PdfName.JPXDecode],
|
||||
[PdfName.FlateDecode]])
|
||||
# test if the colorspace is valid
|
||||
self.assertIn(colorspace, [b"/DeviceGray", b"/DeviceRGB", b"/DeviceCMYK"])
|
||||
self.assertIn(
|
||||
imgprops.ColorSpace, [PdfName.DeviceGray, PdfName.DeviceRGB,
|
||||
PdfName.DeviceCMYK])
|
||||
# test if the image has correct size
|
||||
orig_img = Image.open(f)
|
||||
self.assertEqual(width, orig_img.size[0])
|
||||
self.assertEqual(height, orig_img.size[1])
|
||||
self.assertEqual(imgprops.Width, str(orig_img.size[0]))
|
||||
self.assertEqual(imgprops.Height, str(orig_img.size[1]))
|
||||
# if the input file is a jpeg then it should've been copied
|
||||
# verbatim into the PDF
|
||||
if imgfilter in [b"/DCTDecode", b"/JPXDecode"]:
|
||||
self.assertEqual(imgdata, orig_imgdata)
|
||||
elif imgfilter == b"/FlateDecode":
|
||||
if imgprops.Filter in [[PdfName.DCTDecode], [PdfName.JPXDecode]]:
|
||||
self.assertEqual(
|
||||
x.Root.Pages.Kids[0].Resources.XObject.Im0.stream,
|
||||
convert_load(orig_imgdata))
|
||||
elif imgprops.Filter == [PdfName.FlateDecode]:
|
||||
# otherwise, the data is flate encoded and has to be equal to
|
||||
# the pixel data of the input image
|
||||
imgdata = zlib.decompress(imgdata)
|
||||
if colorspace == b"/DeviceGray":
|
||||
imgdata = zlib.decompress(
|
||||
convert_store(
|
||||
x.Root.Pages.Kids[0].Resources.XObject.Im0.stream))
|
||||
colorspace = imgprops.ColorSpace
|
||||
if colorspace == PdfName.DeviceGray:
|
||||
colorspace = 'L'
|
||||
elif colorspace == b"/DeviceRGB":
|
||||
elif colorspace == PdfName.DeviceRGB:
|
||||
colorspace = 'RGB'
|
||||
elif colorspace == b"/DeviceCMYK":
|
||||
elif colorspace == PdfName.DeviceCMYK:
|
||||
colorspace = 'CMYK'
|
||||
else:
|
||||
raise Exception("invalid colorspace")
|
||||
im = Image.frombytes(colorspace, (width, height), imgdata)
|
||||
im = Image.frombytes(colorspace, (int(imgprops.Width),
|
||||
int(imgprops.Height)),
|
||||
imgdata)
|
||||
if orig_img.mode == '1':
|
||||
orig_img = orig_img.convert("L")
|
||||
elif orig_img.mode not in ("RGB", "L", "CMYK", "CMYK;I"):
|
||||
orig_img = orig_img.convert("RGB")
|
||||
self.assertEqual(im.tobytes(), orig_img.tobytes())
|
||||
# the python-pil version 2.3.0-1ubuntu3 in Ubuntu does not have the close() method
|
||||
# the python-pil version 2.3.0-1ubuntu3 in Ubuntu does not have
|
||||
# the close() method
|
||||
try:
|
||||
im.close()
|
||||
except AttributeError:
|
||||
pass
|
||||
# lastly, make sure that the generated pdf matches bit by bit the
|
||||
# expected pdf
|
||||
with open(out, "rb") as outf:
|
||||
out = outf.read()
|
||||
self.assertEqual(pdf, out)
|
||||
# the python-pil version 2.3.0-1ubuntu3 in Ubuntu does not have the close() method
|
||||
# now use pdfrw to parse and then write out both pdfs and check the
|
||||
# result for equality
|
||||
y = PdfReader(out)
|
||||
outx = BytesIO()
|
||||
outy = BytesIO()
|
||||
xwriter = PdfWriter()
|
||||
ywriter = PdfWriter()
|
||||
xwriter.trailer = x
|
||||
ywriter.trailer = y
|
||||
xwriter.write(outx)
|
||||
ywriter.write(outy)
|
||||
self.assertEqual(outx.getvalue(), outy.getvalue())
|
||||
# the python-pil version 2.3.0-1ubuntu3 in Ubuntu does not have the
|
||||
# close() method
|
||||
try:
|
||||
orig_img.close()
|
||||
except AttributeError:
|
||||
pass
|
||||
setattr(TestImg2Pdf, "test_%s"%test_name, handle)
|
||||
if with_pdfrw:
|
||||
setattr(TestImg2Pdf, "test_%s_with_pdfrw" % test_name, handle)
|
||||
else:
|
||||
setattr(TestImg2Pdf, "test_%s_without_pdfrw" % test_name, handle)
|
||||
|
||||
return unittest.TestSuite((
|
||||
unittest.makeSuite(TestImg2Pdf),
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue