pmaupin / pdfrw

pdfrw is a pure Python library that reads and writes PDFs
Other
1.86k stars 271 forks source link

Pages out of order in booklet.py example #150

Open Jmegan042 opened 6 years ago

Jmegan042 commented 6 years ago

I've been attempting to work with the booklet.py example, and derive a version that can be used in line, but in all of the test pdf's that I've used, the pages are completely out of order, and in a seemingly randomized order.

What am I missing to read in each page, in order?

import os
filename1 = os.path.join("TestPDF.pdf")

from pdfrw import PdfReader, PdfWriter, PageMerge

def fixpage(*pages):
    result = PageMerge() + (x for x in pages if x is not None)
    result[-1].x += result[0].w
    return result.render()

inpfn = filename1
outfn =  os.path.basename(inpfn) +'Booklet_Version'
ipages = PdfReader(inpfn).pages

opages = []
while len(ipages) > 2:
    opages.append(fixpage(ipages.pop(), ipages.pop(0)))
    opages.append(fixpage(ipages.pop(0), ipages.pop()))

opages += ipages

PdfWriter(outfn).addpages(opages).write()

The TestPDF is an article downloaded from an ACS journal, no compression or encryption.

pmaupin commented 6 years ago

The booklet example is designed to print, double-sided, onto multiple 17 x 11" pages, which are then stacked and folded. What are you trying to do?

Jmegan042 commented 6 years ago

I see, I seemed to have misinterpreted what was going on.

I was looking into taking a standard pdf (8.5x11 if printed) and create a two-up layout on a landscape (8.5x11) that could be printed so that page 1 would be on the left and page 2 on the right, next page has 3 and 4, etc.

Effectively: resize, rotate, add second, repeat.

I see now that the booklet option isn't what I was looking for, since it assumes double sided, and I see that it is creating this order so that once it is bound, it plays nice. I suppose I was looking for something akin to adobe's print multiple 2x1 option.

pmaupin commented 6 years ago

I believe there is a separate example for that that was contributed. I don't remember the name at the moment, but there was a previous issue (now closed), where someone proposed a PR to "fix" the booklet example, and then I think they added an example that does what you want or something very similar.

In any case, Python isn't that difficult. All you want to do is take the pages in order, so it would probably be a simple change to the main loop. Remove the second append from the loop, and make the first one take the pages in order:

while len(ipages) > 2:
    opages.append(fixpage(ipages.pop(0), ipages.pop(1)))

That's not the best code, but it should do for your purposes :-)

Regards, Pat

pmaupin commented 6 years ago

Or maybe not. If you want to scale, you could start with the 4up.py example.

Jmegan042 commented 6 years ago

Great suggestion. I was able to solve the whole thing by altering the 4 up layout.

import os
from pdfrw import PdfReader, PdfWriter, PageMerge

def get2(srcpages):
    scale = 0.5
    srcpages = PageMerge() + srcpages
    x_increment,y_increment = (scale * i for i in srcpages.xobj_box[2:])
    for i, page in enumerate(srcpages):
        page.scale(scale)
        page.x = x_increment if i & 1 else 0
    return srcpages.render()

filename1 = os.path.join("TestPDF.pdf")
inpfn = filename1
outfn = '4up.' + os.path.basename(inpfn)
pages = PdfReader(inpfn).pages
writer = PdfWriter(outfn)
for index in range(0, len(pages), 2):
    writer.addpage(get2(pages[index:index + 2]))
writer.write()

Works exactly as intended. It might be a bit sloppy since I'm still defining the y_incriment, but then not passing it to anything, but in the words of Fleetwood Mac: "Oh Well".

Thanks for the suggestion and followup.