Ghostscript, Duplex print same side twice when NumCopies is bigger than 1 - pdf

I using the command :
-q -dBATCH -dNOPAUSE -dNODISPLAY -dPDFFitPage \
-c "mark /BitsPerPixel 1 \
/NoCancel true \
/NumCopies 2 \
/Duplex true \
/OutputFile (%printer%Ricoh c2051) \
/UserSettings << /DocumentName (Arquivo Teste) \
/MaxResolution 500 >> \
(mswinpr2)finddevice putdeviceprops setdevice" -f "C:\Test123.pdf"
The PDF file have 3 pages, when I set the NumCopies 2 for example, the result is 3 pages :
page 1 = the text of page one, in both sides;
page 2 = the text of page two, in both sides;
page 3 = the text of page three, in both sides;
But when I set just one copy the result is 2 pages:
page 1 : the text of page one and in the other side the text of page 2
page 2 : the text of page three and the other side blank .
like Duplex are supposed to be.
Anyone knows how this happened ?

Its a consequence of the way mswinpr2 works, it doesn't care about you setting /Duplex true because the device is not a duplexing device (your printer obviously is, but that's not the same thing). In fact the majority of the command line will have no effect on teh output.
When you set NumCopies, it prints each page 'NumCopies' times to the printer so if your printer is set to do duplexing then it prints the first copy of page 1 on the first side, then the second copy of page 1 on the second side (ie the back of page 1) then the first copy of page 2 on the third side (the front of page 2) and so on.
You cannot achieve multiple collated copies using the mswinpr2 device.
The command line you have set suggests that you have the PostScript option for your printer, you could instead use the ps2write device to convert the PDF to PostScript and send the PostScript to the printer, the latest version of Ghostscript allows for the injection of device-specific options into the output PostScript so you could easily add NumCopies and Duplex there, assuming your printer has sufficient memory to do duplexing and NumCopies at the same time.

Related

PDF Dimensions of Page Out of Range Errors from Ghostscript

I'm trying to produce new PDFs that alter dimensions only the first page (using CropBox). I used a modified version of How do I crop pages 3&4 in a multipage pdf using ghostscript
Here is what's strange: everything runs properly, but when I open the PDFs in typical applications (Preview, Acrobat, etc.), they either crash or I get a "Warning: Dimensions of Page May be Out of Range" error. In Acrobat, only one page will display, even tho page count is 2, 45, 60, or whatever.
Even stranger: I emailed the PDFs to someone to see if it was a machine-specific issue. In Gmail, everything looks fine in Google Apps's PDF viewer. So the process 'worked,' but it looks like there's something about the dimensions or page size that is throwing other apps off.
I've tried multiple GS options (dPDFFitPage, dPrinted=false, dUseCropBox, changing paper size to something other than legal), but nothing seems to work.
I'm attaching a version of a PDF that underwent this process and generates these errors as well. https://www.dropbox.com/s/ka13b7bvxmql4d2/imfwb.pdf?dl=0
Modified output is below. xmin, ymin, xmax, ymax, height, width are variables defined elsewhere in the bigger script of which GS is a part. Data are grabbed using pdfinfo
gs \
-o output/#{filename} \
-sDEVICE=pdfwrite \
-c \"<</EndPage {
0 eq {
pop /Page# where {
/Page# get
1 eq {
(page 1) == flush
[/CropBox [#{xmin} #{ymin} #{xmax} #{ymax}] /PAGE pdfmark
true
}
{
(not page 1) == flush
[/CropBox [0 #{height.to_f} #{width.to_f} #{height.to_f}] /PAGE pdfmark
true
} ifelse
}{
true
} ifelse
}
{
false
}
ifelse
}
>> setpagedevice\" \
-f #{filename}"
`#{cmd}`
For pages after the first you set
[/CropBox [0 #{height.to_f} #{width.to_f} #{height.to_f}] /PAGE pdfmark
I.e. a crop box with zero height!
E.g. in case of your sample document page 2 has the crop box [0 792.0 612.0 792.0].
This surely is not what you want...
If you really want to "produce new PDFs that alter dimensions only the first page (using CropBox)", why do you change the crop box of later pages at all? Simply don't do anything in that case!
Why "Dimensions of Page May be Out of Range"?
Well, ISO 32000-1 in its normative Annex C declares:
The minimum page size should be 3 by 3 units in default user space
Thus, according to that older PDF specification a page height of 0 indeed is out of range for PDF!
Meanwhile, though, ISO 32000-2 has dropped that requirement, so strictly speaking a page height of zero should be nothing to complain about...

Reordering large PDF files using command line tools

I'm working with PDF files that have hundreds of forms within them. Each form is 2 pages long, so in most files pages 1-2 is the first form, pages 3-4 is the second form, and so on.
However, there are several PDF files where the page order of the forms are reversed. In these cases, page 1 is the second page of the first form and page 2 is the first page of the first form, page 3 is the second page of the second form and page 4 is the first page of the second form, and so on.
I want to reorder the page order in these files so that the pages are in this sequence: (2(1), 2(1)-2, 2(2), 2(2)-1, 2(3), 2(3)-1,...,2n,2n-1), where n= total number of pages/2.
I've been looking for a way to do this using command line tools such as cpdf, pdftk, etc., but to no avail. The files are quite large so I would like to do it by using command line tools.
Any advice will be greatly appreciated!
CIB pdf toolbox of CIB (https://www.cib.de) has a (non free) command line tool version, which supports all possibilities of PDF merging in one run.
Did you try poppler-utils?
i think with the command line tools pdfseparate and pdfunite utilities you can achieve all you want.
http://www.manpagez.com/man/1/pdfseparate/
http://www.manpagez.com/man/1/pdfunite/
Would it matter to you if the order of the forms inside the PDF is changed? For example if instead of
form1-reversed,
form2-reversed,
form3-reversed
your resulting file would look like
form3,
form2,
form1
?
In this case you could just run PDFtk so that it completely reverses all the pages of the original file:
pdftk in.pdf cat r1-1 output reversed.pdf
(Prefixing a page number with the letter r references pages in reverse order. That means r1 is the last page...)
In case you are on an operating system which supports shell scripting (like Bash on Linux or macOS), you can achieve the output of your requested page numbers by something like this (assuming that your n==10):
for i in {1..10}; do
echo -n "$(( 2 * ${i} )) ";
echo -n "$(( 2 * ${i} -1 )) ";
done
This will output 2 1 4 3 6 5 8 7 10 9. Now you could use this PDFtk command for re-ordering the pages as you want:
pdftk in.pdf cat $(for i in {1..10};do echo -n "$((2 * ${i})) ";echo -n "$((2*${i}-1 )) ";done) output out.pdf

How do I crop pages 3&4 in a multipage pdf using ghostscript

I would like to crop just some pages in a multipage pdf keeping all pages, some cropped, others not. I tried the following but it "deletes" the non cropped pages...
gswin64.exe -o cropped.pdf -sDEVICE=pdfwrite -dFirstPage=3 -dLastPage=4 -c "[/CropBox [24 72 1559 1794]" -c " /PAGES pdfmark" -f input.pdf
I've seen the posts on different cropping on odd and even pages, but I could not figure out how to apply this to a certain page in a multipage document.
gswin64.exe -o cropped.pdf -sDEVICE=pdfwrite -c "<</EndPage {0 eq {2 mod 0 eq {[/CropBox [0 0 1612 1792] /PAGE pdfmark true}{[/CropBox [500 500 612 792] /PAGE pdfmark true} ifelse}{false}ifelse}>> setpagedevice" -f input.pdf
This does crop all pages according to the settings of the second CropBox. If anybody is wondering about the large margins... I apply this do large drawings.
I have also tried to substitute some operators to only apply the crop to a certain page number: "sub 4" instead of "2 mod" was one attempt to attain the " 0 eq" condition only when the current page number reaches 4.
OK first things first, Ghostscript and the pdfwrite device do not 'modify' an input PDF file. For regular readers; standard lecture here, if you've read it before you can skip the following paragraph.
The way this works is that the input file is completely interpreted into a sequence of graphics primitives which are sent to the device. Rendering devices then call the graphics library to render the primitives to a bitmap, which is then output. High level (vector) devices, such as pdfwrite, translate the primitives into equivalent operations in some high level page description language, and emit that.
So, when you select -dFirstPage and -dLastPage, those are only pages for the input file you are choosing to process. So pdfwrite isn't 'deleting' your pages, you never sent them to the device in the first place.
Now, Ghostscript is a PostScript interpreter, and therefore its action can be affected by writing PostScript programs. In your case you probably want to actually process all the pages (so drop -dFirstPage and -dLastPage), but only write the pdfmark on selected pages.
The way to do this is via a BeginPage or EndPage procedure. If you search here or in the PostScript tag you'll find a number of examples. Fundamentally both procedures are called with a reason code and a count of pages so far.
From memory you will want to check the reason code is 2. If it is, then you want to check the count of pages, and it it matches your criteria (in the case here, count is 3 or 4), execute the /PAGE pdfmark. In any case you want to return 'true' so that the page is emitted.
[EDIT added here]
Hmm, OK I see the problem. What's happening is that the PDF interpreter is calling 'setpagedevice' to set the page size for each page, in case the page size has altered. The problem is that this resets the page count back to 0 each time.
Now, I wouldn't normally suggest the following, because it relies on some undocumented aspects of Ghostscript's PDF interpreter. However, I happen to know that the PDF interpreter tracks the page number internally using a named object called /Page#.
So, if I take the code you wrote, and modify it slightly:
<<
/EndPage {
0 eq {
pop /Page# where {
/Page# get
3 eq {
(page 3) == flush
[/CropBox [0 0 1612 1792] /PAGE pdfmark
true
}
{
(not page 3) == flush
[/CropBox [500 500 612 792] /PAGE pdfmark
true
} ifelse
}{
true
} ifelse
}
{
false
}
ifelse
}
>> setpagedevice
Couple of things to note; there's some debug in there, the lines with '== flush' print out some stuff on the back channel so you know how each page is being handled. If /Page# isn't defined, then the code simply leaves everything alone, this is just some basic safety-first stuff.
Rather than type all this on the command line (which also loses indenting and is hard to read) I stuck it in a file, called test.ps, then invoked GS as:
gswin32c -sDEVICE=pdfwrite -sOutputFile=out.pdf test.ps input.pdf
Its not the neatest solution in the world, but it works for me.

ImageMagick generate pdf with special page numbering

I generate a PDF from a set of PNG files using this command:
convert -- $(ls -v -- src/*.png) out/book.pdf
where there're some files with names like -03.png, which I need to have smaller page numbers than others. But I get a PDF which has -01 having page number 1, -02 number 2, etc., and 01 starts from page number 6.
The PDF is a scanned book, which has some elements like table of contents etc. which aren't included in page numbering. I remember to have seen some PDFs which have special page numbers like vii before normal Arabic numbers start.
I've tried using -scene -5 to add an offset to page numbers, but this didn't change the result.
So what should I instead do to make page "01.png" have page number 1, etc., and previous ones have some other numbers (negative or Latin, anything) and appear at the beginning of the document?
First, you want to sort files numerically counting optional minus sign, which you won't do with command you show.
Second, you talk about PageLabels for PDF pages, which you can add using Ghostscript and pdfmark operator.
Try this command:
ls src/*.png | \
sort -n | \
convert #- pdf:- | \
gs \
-sDEVICE=pdfwrite \
-o out/book.pdf \
-c '[{Catalog}<</PageLabels<</Nums[0<</P(-3)>>1<</P(-2)>>2<</P(-1)>>3<</S/D>>]>>>>/PUT pdfmark' \
-f -
It's for 3 pages -3, -2 and -1, followed by any number of pages labelled 1, 2, 3 etc. Modify according to your needs.

Convert subset of postscript file to pdf documents

I have a system that generates large quantities of PostScript files that each contain multiple, multi-page documents. I want to write a script that takes these large PostScript documents and outputs multiple PDF documents from each.
For example one postscript file contains 200 letters to customers, each of which is 10 pages long. This postscript file contains 2000 pages. I want to output from this 1 ps document, 200x 10 page PDFs, one for each customer.
I'm thinking GhostScript is the way to go for this level of document manipulation but I'm not sure the best way to go - Is there a function in GhostScript to take 'pages 1-10' of the input ps file? Do I have to output the entire ps file as 2000 separate ps files (1 per page) then combine them back together again?
Or is there a much simpler way of acheiving my goal with something other than GhostScript?
Many Thanks,
Ben
Technically this will be possible in the next release of Ghostscript, or using the HEAD code in the Git repository. It is now possible to switch devices when using pdfwrite which will cause the device to close and complete the current PDF file. Switching back again will start a new one.
Combine this with a BeginPage and/or EndPage procedure in the page device dictionary, and you should be able to do something like what you want.
Caveat; I haven't tried any of this, and it will take some PostScript programming to get it to work.
Because of the nature of PostScript, there is no way to extract the 'N'th page from a file, so there is no way to specify a range of pages.
As lsemi suggests you could first convert to one large PDF file and then extract the ranges you want. Ghostscript is able to use the FirstPage and LastPage switches to do this (unlike PostScript, it is possible to extract a specific page from a PDF file).
Well, you might first make the PS into a PDF object collection (or directly generate a PDF from GhostScript by printing to the PDFWriter device), and then "cut" from the big PDF using pdftk, which would be quite fast.
Create the complete PDF file first with the help of Ghostscript:
gs \
-o 2000p.pdf \
-sDEVICE=pdfwrite \
-dPDFSETTINGS=/prepress \
2000p.ps
Use pdftk to extract PDF files with 10 pages each:
for i in $(seq 0 10 199); do \
export start=$(( ${i} * 1 + 1 )); \
export end=$(( ${start} + 9 )); \
pdftk \
2000p.pdf \
cat ${start}-${end} \
output pages---${start}..${end}.pdf; \
done
You can have Ghostscript generate a 2000page sample+test PDF for you by first creating a sample PostScript file named '2000p.ps' with these contents:
%!PS
/H1 {/Helvetica findfont 48 scalefont setfont .2 .2 1 setrgbcolor} def
/pageframe {1 0 0 setrgbcolor 2 setlinewidth 10 10 575 822 rectstroke} def
/gopageno {H1 300 700 moveto } def
1 1 2000 {pageframe gopageno
4 string cvs
dup stringwidth pop
-1 mul 0 rmoveto
show
showpage} for
and then run this command:
gs -o 2000p.pdf -sDEVICE=pdfwrite -g5950x8420 2000p.ps