5.2 KiB
layout | title |
---|---|
docs | Convert Image Files |
{{ page.title }}
Context and Problem Statement
How to convert image files properly to pdf?
Since there are thousands of different image formats, there will never be support for all. The most common containers should be supported, though:
- jpeg (jfif, exif)
- png
- tiff (baseline, single page)
The focus is on document images, maybe from digital cameras or scanners.
Considered Options
- pdfbox library
- imagemagick external command
- img2pdf external command
- tesseract external command
There are no screenshots here, because it doesn't make sense since they all look the same on the screen. Instead we look at the files properties.
Input File
The input files are:
$ identify input/*
input/jfif.jpg JPEG 2480x3514 2480x3514+0+0 8-bit sRGB 240229B 0.000u 0:00.000
input/letter-en.jpg JPEG 1695x2378 1695x2378+0+0 8-bit Gray 256c 467341B 0.000u 0:00.000
input/letter-en.png PNG 1695x2378 1695x2378+0+0 8-bit Gray 256c 191571B 0.000u 0:00.000
input/letter-en.tiff TIFF 1695x2378 1695x2378+0+0 8-bit Grayscale Gray 4030880B 0.000u 0:00.000
Size:
- jfif.jpg 240k
- letter-en.jpg 467k
- letter-en.png 191k
- letter-en.tiff 4.0M
pdfbox
Using a java library is preferred, if the quality is good enough. There is an example for this exact use case.
This is the sample code:
def imgtopdf(file: String): ExitCode = {
val jpg = Paths.get(file).toAbsolutePath
if (!Files.exists(jpg)) {
sys.error(s"file doesn't exist: $jpg")
}
val pd = new PDDocument()
val page = new PDPage(PDRectangle.A4)
pd.addPage(page)
val bimg = ImageIO.read(jpg.toFile)
val img = LosslessFactory.createFromImage(pd, bimg)
val stream = new PDPageContentStream(pd, page)
stream.drawImage(img, 0, 0, PDRectangle.A4.getWidth, PDRectangle.A4.getHeight)
stream.close()
pd.save("test.pdf")
pd.close()
ExitCode.Success
}
Using pdfbox 2.0.18 and twelvemonkeys 3.5. Running time: 1384ms
$ identify *.pdf
jfif.jpg.pdf PDF 595x842 595x842+0+0 16-bit sRGB 129660B 0.000u 0:00.000
letter-en.jpg.pdf PDF 595x842 595x842+0+0 16-bit sRGB 49118B 0.000u 0:00.000
letter-en.png.pdf PDF 595x842 595x842+0+0 16-bit sRGB 49118B 0.000u 0:00.000
letter-en.tiff.pdf PDF 595x842 595x842+0+0 16-bit sRGB 49118B 0.000u 0:00.000
Size:
- jfif.jpg 1.1M
- letter-en.jpg 142k
- letter-en.png 142k
- letter-en.tiff 142k
img2pdf
This is a python tool that adds the image into the pdf without reencoding.
Using version 0.3.1. Running time: 323ms
.
$ identify *.pdf
jfif.jpg.pdf PDF 595x842 595x842+0+0 16-bit sRGB 129708B 0.000u 0:00.000
letter-en.jpg.pdf PDF 595x842 595x842+0+0 16-bit sRGB 49864B 0.000u 0:00.000
letter-en.png.pdf PDF 595x842 595x842+0+0 16-bit sRGB 49864B 0.000u 0:00.000
letter-en.tiff.pdf PDF 595x842 595x842+0+0 16-bit sRGB 49864B 0.000u 0:00.000
Size:
- jfif.jpg 241k
- letter-en.jpg 468k
- letter-en.png 191k
- letter-en.tiff 192k
ImageMagick
The well known imagemagick tool can convert images to pdfs, too.
Using version 6.9.10-71. Running time: 881ms
.
$ identify *.pdf
jfif.jpg.pdf PDF 595x843 595x843+0+0 16-bit sRGB 134873B 0.000u 0:00.000
letter-en.jpg.pdf PDF 1695x2378 1695x2378+0+0 16-bit sRGB 360100B 0.000u 0:00.000
letter-en.png.pdf PDF 1695x2378 1695x2378+0+0 16-bit sRGB 322418B 0.000u 0:00.000
letter-en.tiff.pdf PDF 1695x2378 1695x2378+0+0 16-bit sRGB 322418B 0.000u 0:00.000
Size:
- jfif.jpg 300k
- letter-en.jpg 390k
- letter-en.png 180k
- letter-en.tiff 5.1M
Tesseract
Docspell already relies on tesseract for doing OCR. And in contrast to all other candidates, it can create PDFs that are searchable. Of course, this yields in much longer running time, that cannot be compared to the times of the other options.
tesseract doc3.jpg out -l deu pdf
It can also create both outputs in one go:
tesseract doc3.jpg out -l deu pdf txt
Using tesseract 4. Running time: 6661ms
$ identify *.pdf
tesseract/jfif.jpg.pdf PDF 595x843 595x843+0+0 16-bit sRGB 130535B 0.000u 0:00.000
tesseract/letter-en.jpg.pdf PDF 1743x2446 1743x2446+0+0 16-bit sRGB 328716B 0.000u 0:00.000
tesseract/letter-en.png.pdf PDF 1743x2446 1743x2446+0+0 16-bit sRGB 328716B 0.000u 0:00.000
tesseract/letter-en.tiff.pdf PDF 1743x2446 1743x2446+0+0 16-bit sRGB 328716B 0.000u 0:00.000
Size:
- jfif.jpg 246k
- letter-en.jpg 473k
- letter-en.png 183k
- letter-en.tiff 183k
Decision
Tesseract.
To not use more external tools, imagemagick and img2pdf are not chosen, even though img2pdf shows the best results and is fastest.
Pdfbox library would be the favorite, because results are good and with the twelvemonkeys library there is support for many images. The priority is to avoid more external commands if possible.
But since there already is a dependency to tesseract and it can create searchable pdfs, the decision is to use tesseract for this. Then PDFs with images can be converted to searchable PDFs with images. And text extraction is required anyways.