2013-01-23 27 views
3

我有一个pdf,内容包括幻灯片和每页多个幻灯片。我如何使用ghostscript来分割文件,以便每页有一张幻灯片?用ghostscript将单个页面分割成两页

+0

@KurtPfeifle:没错,我的意思是'pstops'。它有许多低级别的选项,允许您剪切,移动和调整页面的任意部分。但这是最后的解决办法,因为手动设置所有这些偏移是相当不方便的。 – rburny

+0

@rburny:我没有意识到任何具有您提及的功能的“pstops”...(顺便说一句,我将删除我原来的评论,因为我将删除这一个。) –

回答

4

很久以前,我为comp.lang.postscript上的某人编写了一些代码来做到这一点,它也是用于PowerPoint幻灯片。该PostScript代码假设所有'子页面'(即幻灯片)在PDF页面上具有相同的大小和位置,并且所有PDF页面的大小相同。将以下内容保存为名为pdf_slice.ps的文件,并按照注释中的说明使用。

%!PS 
% Copyright (C) 2011 Artifex Software, Inc. All rights reserved. 
% 
% This software is provided AS-IS with no warranty, either express or 
% implied. 
% 
% This software is distributed under license and may not be copied, 
% modified or distributed except as expressly authorized under the terms 
% of the license contained in the file LICENSE in this distribution. 
% 
% For more information about licensing, please refer to 
% http://www.ghostscript.com/licensing/. For information on 
% commercial licensing, go to http://www.artifex.com/licensing/ or 
% contact Artifex Software, Inc., 101 Lucas Valley Road #110, 
% San Rafael, CA 94903, U.S.A., +1(415)492-9861. 
% 
% Slice up a PDF file 
% 
% usage: gs -sFile=____.pdf -dSubPagesX= -dSubPagesY= [-dSubPageOrder=] [-dVerbose=]pdf_slice.ps 
% 
% SubPageOrder is a bit field; 
% Default = 0 
% Bit 0 - 0 = top to bottom 
%   1 = bottom to top 
% Bit 1 - 0 = left to right 
%   1 = right to left 
% Bit 3 - 0 = increase x then y 
%  - 1 = increase y then x 
% 
% 0 - page 1 at top left, increasing left to right, top to bottom 
% 1 - page 1 at bottom left increasing left to right, bottom to top 
% 2 - page 1 at top right, increasing right to left, top to bottom 
% 3 - page 1 at bottom right increasing right to left, bottom to top 
% 4 - page 1 at top left, increasing top to bottom, left to right 
% 5 - page 1 at bottom left increasing bottom to top, left to right 
% 6 - page 1 at top right, increasing top to bottom, right to left 
% 7 - page 1 at bottom right increasing bottom to top, right to left 

% 
% Check the parameters to see they are present and of the correct type 
% 
/Usage { 
    ( usage: gs -dNODISPLAY -q -sFile=____.pdf \n) = 
    ( -dSubPagesX= -dSubPagesY= [-dSubPageOrder=] pdf_slice.ps \n) = 
    (Please see comments in pdf_slice.ps for more details) = 
    flush 
    quit 
} bind def 

/Verbose where not { 
    /Verbose false def 
}{ 
    pop /Verbose true def 
} ifelse 

/File where not { 
    (\n *** Missing source file. \(use -sFile=____.pdf\)\n) = 
    Usage 
} { 
    pop 
}ifelse 

/SubPagesX where not { 
    (\n *** SubPagesX not integer! \(use -dSubPagesX=\)\n) = 
    Usage 
} { 
    Verbose { (SubPagesX) print } if 
    SubPagesX type 
    Verbose { dup == } if 
    /integertype eq not { 
    (\n *** SubPagesX not integer! \(use -dSubPagesX=\)\n) = 
    Usage 
    } 
    pop 
}ifelse 

/SubPagesY where not { 
    (\n *** SubPagesY not integer! \(use -dSubPagesY=\)\n) = 
    Usage 
} { 
    Verbose { (SubPagesY) print } if 
    SubPagesY type 
    Verbose { dup == } if 
    /integertype eq not { 
    (\n *** SubPagesY not integer! \(use -dSubPagesY=\)\n) = 
    Usage 
    } 
    pop 
}ifelse 

/SubPageOrder where not { 
    /SubPageOrder 0 def 
} { 
    Verbose { (SubPageOrder) print } if 
    SubPageOrder type 
    Verbose { dup == } if 
    dup == 
    /integertype eq not { 
    (\n *** SubPageOrder not integer! \(use -dSubPageOrder=\)\n) = 
    Usage 
    } 
    pop 
}ifelse 

% 
% Turns off most messages 
% 
/QUIET true def  % in case they forgot 

%() = 

% 
% Open the PDF file and tell the PDF interpreter to start dealing with it 
% 
File dup (r) file runpdfbegin pop 
/PDFPageCount pdfpagecount def 

% 
% Set up our bookkeeping 
% 
% First get the size of the page from page 1 of the PDF file 
% We assume that all PDF pages are the same size. 
% 
1 pdfgetpage currentpagedevice 
1 index get_any_box 
exch pop dup 2 get exch 3 get 
/PDFHeight exch def 
/PDFWidth exch def 

% 
% Now get the page size of the current device. We are assuming that 
% this is the size of the individual sub-pages in the original PDF. NB 
% This assumes no margins between sub-pages, all sub-pages the same size. 
% 
currentpagedevice /PageSize get 
dup 0 get /SubPageWidth exch def 
1 get /SubPageHeight exch def 

% 
% Calculate the margins. This is the margin between the page border and 
% the enclosed group of sub-pages, we assume there are no borders 
% between sub pages. 
% 
/TopMargin PDFHeight SubPageHeight SubPagesY mul sub 2 div def 
/LeftMargin PDFWidth SubPageWidth SubPagesX mul sub 2 div def 

Verbose { 
    (PDFHeight =) print PDFHeight == 
    (PDFWidth =) print PDFWidth == 
    (SubPageHeight =) print SubPageHeight == 
    (SubPageWidth =) print SubPageWidth == 
    (TopMargin =) print TopMargin == 
    (LeftMmargin =) print LeftMargin == 
} if 

% 
% This rouitne calculates and sets the PageOffset in the page device 
% dictionary for each subpage, so that the PDF page is 'moved' in such 
% a way that the required sub page is under the 'window' which is the current 
% page being imaged. 
% 
/NextPage { 
    SubPageOrder 2 mod 0 eq { 
     /H SubPagesY SubPageY sub SubPageHeight mul TopMargin add def 
    }{ 
     /H SubPageY 1 sub SubPageHeight mul TopMargin add def 
    } ifelse 
    SubPageOrder 2 div floor cvi 2 mod 0 eq { 
     /W SubPageX 1 sub SubPageWidth mul LeftMargin add def 
    }{ 
     /W SubPagesX SubPageX sub SubPageWidth mul LeftMargin add def 
    } ifelse 
    << /PageOffset [W neg H neg]>> setpagedevice 

Verbose { 
    (SubPageX) print SubPageX == 
    (SubPageY) print SubPageY == 
    (X Offset) print W == 
    (Y Offset) print H == flush 
} if 

    PDFPage 
} bind def 

% 
% The main loop 
% For every page in the original PDF file 
% 
1 1 PDFPageCount 
{ 
    /PDFPage exch def 

    % Do the gross ordering here rather than in 
    % NextPage. We eiither process rows and then 
    % columns, or columns then rows, depending on 
    % Bit 3 of SubPageorder 
    SubPageOrder 3 le { 
     1 1 SubPagesY { 
      /SubPageY exch def 
      1 1 SubPagesX { 
       /SubPageX exch def 
       NextPage 
       pdfgetpage 
       pdfshowpage 
      } for 
     } for 
    } { 
     1 1 SubPagesX { 
      /SubPageX exch def 
      1 1 SubPagesY { 
       /SubPageY exch def 
       NextPage 
       pdfgetpage 
       pdfshowpage 
      } for 
     } for 
    } ifelse 
} for 
1

KenS的答案是@howardh应该接受的答案。 KenS使用非常聪明的PostScript语言程序来实现结果。 (请务必记住KenS所说的话:如果所有'子页面'(即幻灯片)在PDF页面上的大小和位置都相同,并且所有PDF页面的大小相同,则他的解决方案仅适用于')。

然而,为了完整性,让我链接到其他几个以前的答案(其中一些所示),这解决了类似的问题:

这些答案也使用PostScript代码,但只作为被传递到的Ghostscript在命令行 '片段'。 (如果您不懂PostScript,那么这些可能会更容易修改,并适用于PDF页面中“子页面”的大小和位置不同且PDF页面大小不同的情况。)

1

我想提出一个解决方案,那其实
1)拆分一个PS或PDF页面许多单独的页面和
2)然后合并的* .pdf到多页PDF。 但该解决方案不处理边距。

这个脚本在Linux中BASH工作:

INPUT="input.ps" ; 
RESOLUTION=72 ; 
WHOLE_WIDTH=598 ; # current size of portrait A4 
WHOLE_HEIGHT=843 ; 
COLOUMNS=2 ; # split vertically 
ROWS=1 ; # split horizontally 
PAGE_WIDTH=$((WHOLE_WIDTH/COLOUMNS)) ; 
PAGE_HEIGHT=$((WHOLE_HEIGHT/ROWS)) ; 

# Split: 

for x in `seq 1 ${COLOUMNS}` ; do 
    for y in `seq 1 ${ROWS}` ; do 
    gs -dBATCH -dNOPAUSE -dSAFER \ 
    -o gramps_tmp_${x},${y}.pdf \ 
    -r${RESOLUTION} \ 
    -sDEVICE=pdfwrite \ 
    -g${PAGE_WIDTH}x${PAGE_HEIGHT} \ 
    -c "<</PageOffset [$(((x - 1)*(0 - PAGE_WIDTH))) \ 
         $(((y - 1)*(0 - PAGE_HEIGHT)))]>> setpagedevice" \ 
    -f "$INPUT" ; 
    done ; 
done ; 

# Merge: 

gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=singleCombinedPdfFile.pdf -dBATCH gramps_tmp_*.pdf ; 

但我们可安排在需要的顺序页面:

ORDERED="tmp_1,1.pdf tmp_1,2.pdf" ; 
gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=singleCombinedMultipagePdfFile.pdf -dBATCH ${ORDERED};