Search code examples
pdfghostscriptpdftkimposition

Cutting pdf page in half and reimposing parts differently using ghostscript


I'm looking for a ghostscript (or other commandline) command to reimpose a pdf page so that the elements on the left side are copied to the right. Like so: schematic view of reimposition

The size of the page shouldn't change (each page is cropped and cut differently), and while I could supply the final size manually, it would be neater to read it from the original pdf.

For the sake of simplicity, let's assume that the input file has only one page.

I've come up with an extremely complicated series of commands, involving

  • reading the CropBox with pdfinfo
  • copying the file and changing the cropbox so that the left half is shortened and the right half is extended with the -c "[/CropBox [*new dimensions*] /PAGES pdfmark" command
  • copying the file and changing the cropbox so that the left half remains
  • reprocessing this file with the old page dimensions -g "PageDimension" and -c \"<<\/Install{1 1 scale WithOfRightside 0 translate}>> setpagedevice\"
  • use pdftk to merge the two new files into one page: pdftk.exe lefthalf.pdf background righthalf.pdf output combinedfile.pdf

I couldn't get this to work satisfactorily, however, and I don't like either the series of steps involved or the number of tools invovled. Surely all the steps could be performed with ghostscript and in fewer steps (and less reprocessing of the original).


Solution

  • I have finally come up with a useful solution - though it does not reflect the original question fully.

    This solution is based on (proprietary) Acrobat, and uses the Acrobat JavaScript interface - not GhostScript. But the following script works beautifully, which is why I decided to share it:

    /*
     * Acrobat PDF script
     * transpose part of left page to right side and recrop document
     */
    
    // define cutting line, in points from left
    var cuttingline = 300;
    
    /* define offset(s)  ---  if uncertain, leave at 0
       a) of new left page border, 
       b) of transposed half of page
       
       WATCH OUT: 
       a) may expose material from original left half when negative
       b) may expose material from original right half when negative - leave "correctcrop" true to avoid this.
    */
    var offsetleft = 5;
    var offsettransposition = -50;
    var correctcrop = true;
    
    // cut off left page and add as much white space to right, then insert left part of page on top right
    for (var p = 0; p < this.numPages; p++) {
      // add white space to media box right
      console.println("\nPage " + (p + 1));
      var aRect = this.getPageBox("Media", p);
      console.println("Original media box: " + aRect);
      aRect[2] += cuttingline + offsettransposition;
      console.println("New media box: " + aRect);
      this.setPageBoxes("Media", p, p, aRect);
    
    
      // Add copy of page as overlay, shifted to the right
      this.addWatermarkFromFile({
        cDIPath: this.path,
        nSourcePage: p,
        nStart: p,
        nEnd: p,
        nHorizAlign: app.constants.align.left,
        nVertAlign: app.constants.align.bottom,
        nHorizValue: aRect[2] - cuttingline + offsettransposition,
        nVertValue: 0
      });
    
      // crop left, add space to crop box right to reveal page copy
      var aRect = this.getPageBox("Crop", p);
      console.println("Original crop box: " + aRect);
      aRect[0] += cuttingline + offsetleft;
      aRect[2] += cuttingline + offsettransposition + (((correctcrop == true) && (offsettransposition < 0)) ? offsettransposition : 0);
      console.println("New crop box: " + aRect);
      this.setPageBoxes("Crop", p, p, aRect);
    }
    
    // flatten layers
    this.flattenPages();

    Please take note: this doubles the page content. Use a Preflight profile or Acrobat's document cleanup-tools to remove the (invisible) page contents.