7

I have a few ebooks scanned from originals. They're formatted so that a single PDF page contains two actual pages: one on the left, and one on the right.

I want to programmatically split each PDF page into two, so the left 50% of PDF page 1 becomes page 1 and its right becomes page 2, and so on for all the pages.

Does anyone know of a command line utility or script that could help with this?


Output from pdfimages -list -f 1 -l 1 file.pdf:

page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image    1921  1561  rgb     3   8  jpeg   no       643  0   200   200  200K 2.3%
   1     1 stencil     1     1  -       1   1  image  no   [inline]   0.692     2    -    - 
   1     2 stencil     1     1  -       1   1  image  no   [inline]   0.722 0.650    -    - 
   1     3 stencil     1     1  -       1   1  image  no   [inline]       3     3    -    - 

Second PDF:

page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image     456   625  gray    1   8  jpx    yes      251  0    72    72 11.7K 4.2%
  • In the past I have successfully used a command line tool "mutool" to extract / slice-up PDF files. It's part of the mupdf package (see: mupdf.com). I don't know if it will work for you in this case however, as far as I understand the above output from pdfimages, your pdf file(s) seem to consist mostly of (or are a wrapper around) a single large JPEG image ... – Robb W. Nov 26 '17 at 1:10
8
+100

This should work it needs pdftk tool ( and ghostscript ).

A simple case:

Step One: Split into individual pages

 pdftk clpdf.pdf burst

this produces files pg_0001.pdf, pg_0002.pdf, ... pg_NNNN.pdf, one for each page. It also produces doc_data.txt which contains page dimensions.

Step Two: Create left and right half pages

  pw=`cat doc_data.txt  | grep PageMediaDimensions | head -1 | awk '{print $2}'`
  ph=`cat doc_data.txt  | grep PageMediaDimensions | head -1 | awk '{print $3}'`
  w2=$(( pw / 2 ))
  w2px=$(( w2*10 ))
  hpx=$((  ph*10 ))
  for f in  pg_[0-9]*.pdf ; do
   lf=left_$f
   rf=right_$f
   gs -o ${lf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [0 0]>> setpagedevice" -f ${f}
   gs -o ${rf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [-${w2} 0]>> setpagedevice" -f ${f}
  done

Step Three: Merge left and right in order to produce newfile.pdf containing single page .pdf.

  ls -1 [lr]*_[0-9]*pdf | sort -n -k3 -t_ > fl
  pdftk `cat fl`  cat output newfile.pdf 

A more general case:

  1. The example above assumes all pages are same size. The doc_data.txt file contains size for each split page. If the command

    grep PageMediaDimensions <doc_data.txt | sort | uniq | wc -l

    does not return 1 then the pages have different dimensions and some extra logic is needed in Step Two.

  2. If the split is not exactly 50:50 then a better formula than w2=$(( pw / 2 )), used in the example above, is needed.

This second example shows how to handle this more general case.

Step One: split with pdftk as before

Step Two: Now create three files that contain the width and height of each pages and a default for the fraction of the split the left page will use.

  grep PageMediaDimensions <doc_data.txt | awk '{print $2}'    >   pws.txt
  grep PageMediaDimensions <doc_data.txt | awk '{print $3}'    > phs.txt
  grep PageMediaDimensions <doc_data.txt | awk '{print "0.5"}' > lfrac.txt

the file lfrac.txt can be hand edited if information is available for where to split different pages.

Step Three: Now create left and right split pages, using the different pages sizes and (if edited) different fractional locations for the split.

#!/bin/bash
exec 3<pws.txt
exec 4<phs.txt
exec 5<lfrac.txt

for f in  pg_[0-9]*.pdf ; do
 read <&3 pwloc
 read <&4 phloc
 read <&5 lfr
 wl=`echo "($lfr)"'*'"$pwloc" | bc -l`;wl=`printf "%0.f" $wl`
 wr=$(( pwloc - wl ))
 lf=left_$f
 rf=right_$f
 hpx=$((  phloc*10 ))
 w2px=$(( wl*10 ))
 gs -o ${lf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [0 0]>> setpagedevice" -f ${f}
 w2px=$(( wr*10 ))
 gs -o ${rf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [-${wl} 0]>> setpagedevice" -f ${f}
done

Step Four: This is the same merge step as in the previous, simpler, example.

  ls -1 [lr]*_[0-9]*pdf | sort -n -k3 -t_ > fl
  pdftk `cat fl`  cat output newfile.pdf 
4

You can widen your choice of tools by converting the pdf to PostScript as follows, then using pstops. I've assumed we start from an A4 portrait page showing two pages as they might have been scanned from an open book, with the spine going horizontally through the middle, like this:

original

Obviously, you can change the values in the solution below to fit your precise case.

You can convert this pdf to PostScript with pdf2ps (which is part of the ghostscript package). Then tool pstops from package psutils, can be used to rotate the page right (clockwise) around the bottom left corner, rescale it and move the result up so that only the bottom half covers a whole page:

one page

A second page can be created from the same original page by a similar rotation, scale, and translation. The result can be converted back to pdf. A single command can draw each page onto 2 new pages:

pdf2ps myfile.pdf out.ps
pstops -p a4 '0R@1.2(1cm,29cm),0R@1.2(-16cm,29cm)' out.ps new.ps
ps2pdf new.ps new.pdf

The syntax is explained in the man page. Here we have R for rotate right, @1.2 to scale, (x,y) to move the result. The comma (,) produces 2 pages from each original page.

Note that this will double the size of the resulting pdf, since each page is fully drawn twice, even though you only see half of it each time.

3

You want Libpoppler, or more precisely the pdfimages tool therein. It is free software, will extract the images from the PDF. If the PDF contains scanned images, they are not always oriented correctly, off by a few degrees. If the page contains two images, one for each scanned page, it becomes easy ... if not, you will have to cut them manually (dirty) or try ImageMagick to split them.

http://poppler.freedesktop.org/

http://en.wikipedia.org/wiki/Pdfimages

Taken from stackoverflow.

2

You might want to look at imagemagick:

$ convert -resize 1000x1000 /links/www/Salix/pdf/index.pdf a.jpg
$ convert -crop 500x1000+0+0  a.jpg b.jpg
$ convert -crop 500x1000+500+0 a.jpg c.jpg
$ convert c.jpg c.pdf
$ convert b.jpg b.pdf
1

I suggest PDFjam and its daughter script PDFjoin. First crop the left side and save as left.pdf and then crop the right side and save as right.pdf and then merge individual pages of the two files. You can read the examples on the page for inspiration. If that’s too easy for you, you could go the Ghostscript route, but then you’ll have to do some pixel math, external page counting and a final concat etc.

Don’t go the jpg route - you’ll get crazy file bloat and artifact generation.

0

PDFcreator has a com plugin you may be able to communicate to. But you need the "plus" edition, which is $10 a year.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.