2013-01-23 45 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};