1
 
 

When a scanned document is slightly rotated anti-clockwise, this causes a problem for OCR because the 2nd half of every line appears before the 1st half of every line. The incorrect order is a disaster for language translations.

The FOSS tool to deskew is unpaper. But it often fails to deskew. There are --pre-rotate and --post-rotate options which you might expect to give some manual control, but strangely you can only rotate by 90°. The unpaper options are not well explained.

What are folks doing in this situation?

I recall from ~20 years ago Windows paperless tools had a deskewing function that was manual. You draw a line under a line of text on the page and that input is used for rotation. It was limited to PDFs but at least it worked. Is there anything like that in the free world?

2
 
 

Suppose you have a scanned document. Scans are flawed, ugly, bulky, and sometimes contain sensitive info. How do you produce a clean vector PDF from that?

In the FOSS world, we have #Tesseract to OCR the PDF. This just generates the text for searchability but retains the ugliness and bulk. It would be crazy painful to extract the text and then use LaTeX to manually reconstruct the layout.

Windows has a tool named ABBYY FineReader Pro Edition. It performs the OCR, then it also finds text and images and puts numbered rectangles around them. It finds a matching font, style, and weight for the text and gives users a chance to delete rectangles at will before constructing a new vector PDF. I took the scan of a 1-page letter and dithered it to bitonal using FOSS, yielding 43k. Then processed with ABBYY, which produced a much cleaner vector PDF weighing in at 12kb. Most importantly, ABBYY makes it easy to omit sensitive blocks like names, addresses, and signatures, or overwrite them with “REDACTED”.

Is there anything like this in the FOSS world? I suppose not, but please correct me if I’m wrong.

I would love it if a tool could take an OCRd PDF and produce a LaTeX doc where every object would simply amount to a \put command with coordinates in a picture environment, so it could be edited in LaTeX.

Potential use cases:

  1. Whistle-blowing. E.g. someone wants to leak a document but needs to strip it of forensic artifacts and certain sensitive data.
  2. Activism. E.g. you complain to a public administration about some injustice, and they give a shitty anti-human reply. Simply publishing the response can help dish out some shame and embarrassment. But you probably don’t want your personal details like your address exposed, and you probably have to scrub the name of the administrator to respect their GDPR rights.
  3. Digitizing paper books. You have a bound book but as you travel space and weight is scarce. You need an electronic format, perhaps even just as a backup. A raster scan is bulky, messy and does not scale well on different screens.
  4. Binary blobs are not great for a version control system. Converting raster scans to quasi-text vector files makes edits possible as well as tracking the history of changes.

Update

FOSS libraries apparently already exist.

3
 
 

This is how I currently edit PDF bookmarks:

$ pdftk "$pdf_file" dump_data > /tmp/bookmarks.txt
$ emacs !$&
$ pdftk "$pdf_file" update_info /tmp/bookmarks.txt output new.pdf
$ mv new.pdf "$pdf_file"

It’s only great in some situations. It’s not great if there are no pre-existing bookmarks because there is no structure to edit. I then have to find another PDF that has bookmarks, then copy the structure into the metadata dump of the PDF that needs bookmarks, and edit that hoping that I made no mistakes. A sample of the metadata looks like this:

PDF bookmark metadata

BookmarkBegin  
BookmarkTitle: CHAPTER I: GENERAL PROVISIONS  
BookmarkLevel: 1  
BookmarkPageNumber: 9  
BookmarkBegin  
BookmarkTitle: Article 1: Subject matter and objectives  
BookmarkLevel: 2  
BookmarkPageNumber: 9  
BookmarkBegin  
BookmarkTitle: Article 2: Scope  
BookmarkLevel: 2  
BookmarkPageNumber: 9  
BookmarkBegin  
BookmarkTitle: Article 3: Definitions  
BookmarkLevel: 2  
BookmarkPageNumber: 10  
…  
PageMediaBegin  
PageMediaNumber: 1  
PageMediaRotation: 0  

Notice there is no “BookmarkEnd” lines in this, so the structure is not exactly intuitive. It’s prone to human error.

Is there a simpler tool for making minor additions? Evince is purely a viewer.

Okular has an “add bookmark” feature but it uses bookmark to mean something else. What other tools call bookmarks is called “Contents” in Okular. On the Contents sidebar you can right-click and “add bookmark” but that does not change the table of contents. Instead, that creates a reference/hook in another tab called “Bookmarks”. Okular’s nomenclature is more true to the intuitive meaning people expect, but it deviates from PDF norms. Anyway, Okular cannot handle the job.

4
 
 

Before posting an image to the fedi, I want to be mindful about the network burden it will cause. I’m only uploading the image once but potentially thousands of people could end up downloading it.

If it’s a color image, then JPG is typically best. This #ImageMagick command reduces the filesize quite a bit, trading off quality:

  $ convert "$original_image_file" \
    +dither \
    -posterize 8 \
    -sampling-factor 4:2:0 \
    -strip \
    -quality 75 \
    -interlace Plane \
    -gaussian-blur 0.05 \
    -colorspace RGB \
    -strip \
    smaller_file.jpg

If it’s a pic of a person, this processing will likely be a disaster. But for most things where color doesn’t matter too much, it can be quite useful. Play with different -posterize values.

If you can do with fewer pixels, adding a -resize helps.

  $ convert "$original_image_file" -resize 215x smaller_file.jpg

If you can get away with black and white, jpeg is terrible. Use PNG instead. E.g.

  $ convert "$original_image_file" -threshold 30% -type bilevel smaller_file.png

For privacy, strip the metadata

The ImageMagick -strip option supposedly strips out metadata. But it’s apparently not thorough because the following command yields a slightly smaller file size:

  $ exiftool -all= image.jpg

What else?

Did I miss anything? Any opportunities to shrink images further? In principle the DjVu format would be more compact but it’s not mainstream and apparently not accepted by Lemmy.

5
 
 

I scanned an envelope which had a dot matrix 4-state barcode by the postal service. It did not appear on the /bilevel/ scan. So I tried very low thresholds (the point at which light gray is treated as either black or white). The threshold needed to retain the fluorescent(†) barcode is so low that black text on the same scan becomes too dirty for OCR to work.

The US postal service scans (all?) envelopes and thus has records of who is sending mail to who. (Do other countries do this?) Anyway, I wonder how we might counter the privacy intrusion. What if the return address on an envelope is printed in fluorescent orange.. would the return address be suppressed from envelope scans? IIUC, they would have to scan in grayscale or color to capture it, which would take a lot more storage space. So they are probably doing bitonal scans. Yellow would work too but it’s much harder for an eye to see. This fluorescent orange is readable enough to a human eye but apparently tricky for a machine.

Of course the return address is optional, so the best privacy is to simply not supply a return address. But if return service is wanted, supplying a return address is inherently needed.

Another thought: suppose an address is dark blue text on a light blue background, or white text on a medium blue background. The scanning software would have to be quite advanced to choose a threshold that treats the text differently than the background, no? If the return address is fluorescent orange and the destination address has a background color, envelopes could perhaps be printed in a way that stifles the mass surveillance.

(†) I cannot concretely assert that it is fluorescent; just describing what it looks like.

6
 
 

I was able to embed an EPS file in the source so that the compiler generates the image that the document re-imports. EPS files have different formats and some of them fail because they are binary, so it’s a dicey process.

what worked

I started with a large JPG which I was importing this way:

\includegraphics[width=18mm]{big.jpg}

Looked nice but quite wasteful as the whole JPG ends up inside the PDF only to be scaled down to 18mm wide. So I needed to resample it. But I also need to distribute the tex doc and really can’t be dealing with distributing multiple files. EPS files can be simple ascii text and they can be embedded in the code. So I ran ImageMagick to shrink the image and produce an EPS file:

$ convert big.jpg -geometry 100x small.eps

The the scaling option (width=18mm) can now be omitted: \includegraphics{small.eps}. It was the right size but blurry. WTF? I don’t know the problem exactly but I recall that ImageMagick has some shitty defaults that ignore attributes of the original image, thus forcing users to figure out what parameter to provide in order to maintain original attributes.

I could not be bothered to investigate. So I made the image 50% bigger than needed and made latex rescale it (sloppy but works):

$ convert big.jpg -geometry 150x medium.eps

In LaTeX: \includegraphics[width=18mm]{medium.eps}

Job done. But sloppy because I should not have to make the image bigger than displayed and then downscale it in LaTeX to avoid blurr.

better, but fails

So I used #GIMP to shrink the image. GIMP is a different kind of shit-show because it crashes Wayland, but I was finally able to scale the image faster than GIMP could crash and GIMP did a good job. That is, the EPS file was the right size and without getting blurry. Thus the resampling was proper.

But the EPS file produced by GIMP is not ascii text. It has some characters that fuck up the ability to embed the image in the source code. Fuck me. There are different EPS flavors and even a badly documented eps2eps tool.

Perhaps I have to use GIMP to scale to a PPM and then ImageMagick to convert the PPM to EPS without scaling. Assuming that works, an annoyance remains: an EPS ascii text file from ImageMagick has many lines which requires a lot of scrolling to reach the LaTeX code after it’s embedded in the code. Are there any other non-binary image formats apart from (e)ps?

PDF is a one. A PDF can also be binary or ascii. If the effort is made to ensure an ascii PDF, I think the downside is the final document is no longer versatile (can only be PDF not PostScript).

SVG is another ascii image format but I’m not confident LaTeX handles it well.

I am tempted to follow this approach to make a definitively ascii EPS file. But it would be useful if there were a way to make an EPS file that has no more than 20 or so linefeeds.

There is an inline-images package.. I might fiddle with that if the EPS gives too much issue.

Update

I looked more into ImageMagick. The complexity is staggering because there are six approaches to minifiscation:

-sample -resample -scale -resize -adaptive-resize -thumbnail

Resizing turns out to serve my purpose well. But then there are 30 different filters listed by convert -list filter. So I tried them all:

convert -list filter| while read fltr; do convert source.jpg -filter "$fltr" -resize 215x "$fltr"215x.eps; done
montage *215x.eps -tile 8x miff:- | display -

They all looked the same AFAICT and all were decent. So I just used the default filter in the end. I’m glad I could ditch GIMP given how badly it behaves on Wayland. The encoding from ImageMagick is very safe for embedding in LaTeX docs, as it seems to use only HEX symbols (0-9,a-f). Here is a sample:

4D4D48454342413E3D3F3F40403F3B3A3C3D40413E393835322D26211B1C1B191C1B1C1A
1A19171314172828292B3844474C4B5256554B44474B555B5C5A585857585C63676F777F
868C8D9096999CA0A2A3A6A7A7A9AAACADAFB1B1B1B2B4B6BABCBDBEBEBFBEBEC285302F
442F11120D0E1B32230F14201B0D101B23231418293E42514A6A4653605B393F4B523C4C

OTOH, it’s so limited that an image of approximately ~18x25 mm ends up taking almost 1600 lines of text in the document.

GIMP’s output is apparently also ascii. I don’t know how to test that other than to grep it for something arbitrary and see if grep prints that the file is binary. The encguess command prints US-ASCII. GIMP uses a broader range of ASCII which is normally preferred but something causes pdflatex to choke on it.