用于PDF的Ghostscript:如何将4页变成1页? [英] Ghostscript for PDF: how to fit 4 pages into 1?

查看:78
本文介绍了用于PDF的Ghostscript:如何将4页变成1页?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用ghostscript将多个PDF串联为一个pdf文件. 我需要您提供的帮助是我必须使用什么命令,以便编辑输出页面,以使其适合输入文件的4个页面,使其适合输出的1个页面. 到目前为止,我正在使用的命令是:

I need to use ghostscript for concatenating several PDFs into a single pdf file. The help I need from you is what command do I have to use, in order to edit the output page, so that it fits 4 pages of the input files, into 1 of the output. What I am using so far is this command:

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite \
   -sOutputFile=ALL.pdf plot_1.pdf plot_n.pdf

输入文件为A4横向,输出必须为相同格式.

Input files are A4 landscape, and the output have to be the same format.

感谢所有人, 克里斯蒂安(Cristian)

Thanks to all, Cristian

推荐答案

这是我写了一段时间的程序,用于从PDF进行2合拼版.这不是不是通用PostScript程序,它仅适用于Ghostscript(因为它利用了某些GS内部构件),并且仅在输入为PDF时才适用,而不适用于PostScript.

This is a program I wrote some time back to do 2-up imposition from PDF. This is not a general purpose PostScript program, it will only work with Ghostscript (as it makes use of some GS internals) and only when the input is PDF, not PostScript.

您将必须对其进行修改以进行4合一拼版.不用担心可怕的许可问题,那仅仅是因为我从其他地方复制了样板.

You will have to modify it to do 4-up imposition. Don't worry about the scary licencing stuff, that's just because I copied the boilerplate from somewhere else.

您可能想假设所有页面的尺寸都是相同的,这与该代码允许不同的方向不同.

You'll probably want to assume that all pages are the same size and orientation, unlike this code which allows for different orientations.

%!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.
%
% Make a PDF file '2-up'
% This program deliberately does NOT attempt to preserve metadata
% such as DEST links, bookmarks and so forth as these will be
% mostly incorrect after imposition.
%
% usage: gs -dNODISPLAY -sFile=____.pdf [-dVerbose] 2-up.ps

%
% Make, and open, a working dictionary to store stuff
%
/PDF_2UPDict 20 dict dup begin def  

%
% Check the parameters to see they are present and of the correct type
%

/Usage {
  (  usage: gs -dNODISPLAY -q -sFile=____.pdf [-dVerbose] 2-up.ps\n) =
  flush
  quit
} bind def

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

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

%%
%% This code is copied from pdf_main.ps, pdfshowpage_finish
%% sadly that routine always calls showpage, and we want that
%% to be under our control, so we have to duplicate the code
%% here. Not only that but it uses GS extensions which aren't
%% available outside of startup, so some things it simply can't
%% replicate. As a result some of the error handling is less
%% good.
%%
%% I plan to extend the PDF interpreter with two new
%% routines, pdfnoshowpage_finish and then have both
%% that and pdfshowpage_finish call pdfoptionalshowpage_finish
%% which will take a boolean determining whether to actually
%% call the showpage. At that time we'll alter this code.
%%
/draw_page_content {    % <pagedict> pdfshowpage_finish -
   save /PDFSave exch store
   /PDFdictstackcount countdictstack store
   /PDFexecstackcount count 2 sub store
   (before exec) VMDEBUG

   % set up color space substitution (this must be inside the page save)
   pdfshowpage_setcspacesub

        % Display the actual page contents.
   8 dict begin
   /BXlevel 0 def
   /BMClevel 0 def
   /OFFlevels 0 dict def
   /BGDefault currentblackgeneration def
   /UCRDefault currentundercolorremoval def
        %****** DOESN'T HANDLE COLOR TRANSFER YET ******
   /TRDefault currenttransfer def
  matrix currentmatrix 
  2 dict
  dictbeginpage setmatrix
  /DefaultQstate qstate store

  count 1 sub /pdfemptycount exch store
        % If the page uses any transparency features, show it within
        % a transparency group.
  dup pageusestransparency dup /PDFusingtransparency exch def {
    % Show the page within a PDF 1.4 device filter.
    0 .pushpdf14devicefilter {
      /DefaultQstate qstate store       % device has changed -- reset DefaultQstate
      % If the page has a Group, enclose contents in transparency group.
      % (Adobe Tech Note 5407, sec 9.2)
      dup /Group knownoget {
        1 index /CropBox pget {
          /CropBox exch
        } {
          1 index get_media_box pop /MediaBox exch
        } ifelse
        oforce_elems normrect_elems fix_empty_rect_elems 4 array astore .beginformgroup 
        showpagecontents
        .endtransparencygroup
      } {
        showpagecontents
      } ifelse
    } stopped {
      % abort the transparency device 
      .abortpdf14devicefilter
      /DefaultQstate qstate store   % device has changed -- reset DefaultQstate
      stop
    } if .poppdf14devicefilter
    /DefaultQstate qstate store % device has changed -- reset DefaultQstate
  } {
    showpagecontents
  } ifelse
  .free_page_resources
  % todo: mixing drawing ops outside the device filter could cause
  % problems, for example with the pnga device.

  end           % scratch dict
  % Some PDF files don't have matching q/Q (gsave/grestore) so we need
  % to clean up any left over dicts from the dictstack

  PDFdictstackcount //false
  { countdictstack 2 index le { exit } if
    currentdict /n known not or
    end
  } loop 

  pop
  count PDFexecstackcount sub { pop } repeat
  Repaired      % pass Repaired state around the restore
  PDFSave restore
  currentglobal pdfdict gcheck .setglobal
  .setglobal
  /Repaired exch def
} bind def

%%
%% First we open the PDF file
%%
File dup (r) file runpdfbegin pop
process_trailer_attrs

%%
%% FInd out how many pages are in teh PDF file
%%
/PDFPageCount pdfpagecount def

Verbose {(PageCount is ) print PageCount ==} if

%
% 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 get_any_box 
exch pop dup 2 get exch 3 get
/PDFHeight exch def
/PDFWidth exch def
PDFWidth PDFHeight gt {
/PDFLandscape true def
}{
/PDFLandscape false def
}ifelse

Verbose{
(PDFHeight is ) print PDFHeight ==
(PDFWidth is ) print PDFWidth ==
(PDFLandscape is ) print PDFLandscape ==
} if

%
% Now get the page size of the current device. We will fit
% the PDF pages onto this using rotation and scaling as
% required.
%
currentpagedevice /PageSize get
dup 0 get /PageWidth exch def
1 get /PageHeight exch def
PageWidth PageHeight gt {
/PageLandscape true def
}{
/PageLandscape false def
}ifelse

Verbose{
(PageHeight is ) print PageHeight ==
(PageWidth is ) print PageWidth ==
(PageLandscape is ) print PageLandscape ==
} if

%
% Now figure out how best to fit the pages 2-up
%
PageLandscape PDFLandscape and {
  %% Both landscape
  /ScaleY PageHeight PDFWidth div
  /ScaleX PageWidth 2 div PDFHeight div
  ScaleX ScaleY lt {
    /Scale ScaleX def
  } {
    /Scale ScaleY def
  }ifelse
  /Rotate 90
  /OriginYTx PDFHeight neg def
  /OriginXTx 0 def
  /PageYTx PDFHeight def
  /PageXTx 0 def
}{
  PageLandscape {
    %% Page is landscape, PDF is portrait
    /ScaleY PageHeight PDFHeight div def
    /ScaleX PageWidth 2 div PDFWidth div def
    ScaleX ScaleY lt {
      /Scale ScaleX def
    } {
      /Scale ScaleY def
    }ifelse
    /Rotate 0 def
    /OriginXTx 0 def
    /OriginYTx 0 def
    /PageXTx PDFWidth def
    /PageYTx 0 def
  }{
    PDFLandscape {
      %% PDF is landscape, Page is portrait
      /ScaleY PageHeight 2 div PDFHeight div def
      /ScaleX PageWidth PDFWidth div def
      ScaleX ScaleY lt {
        /Scale ScaleX def
      } {
        /Scale ScaleY def
      }ifelse
      /Rotate 0 def
      /OriginXTx 0 def
      /OriginYTx PDFHeight def
      /PageXTx 0 def
      /PageYTx PDFHeight neg def
    } {
      %% Both portrait
      /ScaleY PageHeight 2 div PDFWidth div def
      /ScaleX PageWidth PDFHeight div def
      ScaleX ScaleY lt {
        /Scale ScaleX def
      } {
        /Scale ScaleY def
      }ifelse
      /Rotate 90 def
      /OriginXTx 0 def
      /OriginYTx PDFHeight neg def
      /PageYTx 0 def
      /PageXTx PDFWidth def
    } ifelse
  }ifelse
} ifelse

Verbose{
(ScaleX is ) print ScaleX ==
(ScaleY is ) print ScaleY ==
(Scale is ) print Scale ==
(Rotate is ) print Rotate ==
(OriginXTx is ) print OriginXTx ==
(OriginYTx is ) print OriginYTx ==
(PageXTx is ) print PageXTx ==
(PageYTx is ) print PageYTx ==
} if

%
% Starting at 0, count by 2, and stop at the last page, however
% account for the fact that the number of pages in the PDF
% file may not be even, in which case draw a final empty
%page
%
0 2 PDFPageCount 1 sub PDFPageCount 2 mod add {
                                                             %% loop counter
  save                                                       %% save the state
    exch                                                     %% exch the save state and the loop counter
    Rotate rotate                                            %%
    Scale Scale scale                                        %% set up our calculated CTM
    OriginXTx OriginYTx translate                            %%
    save                                                     %% and save this too
      exch                                                   %% swap the save state and the loop counter
      dup 1 add                                              %% copy the loop counter, then add 1, stack: -save- -save- loop loop+1
      Verbose {(Drawing page ) print dup ==} if
      0 0 PageWidth PageHeight rectclip                      %% clip the page contents to the page size (in case of bleeds)
      pdfgetpage                                             %% get the page from the PDF file, stack: -save- -save- loop -dict-
      dup /Page exch store                                   %% save a copy of the page dict inside itself
      pdfshowpage_init                                       %% initialise the page
      draw_page_content                                      %% se above, draws the graphical objects, stack -save- -save- loop
      exch                                                   %% swap back teh save object, stack: -save- loop -save-
    restore                                                  %% restore back to our calculated CTM
    PageXTx PageYTx translate                                %% Move to draw page 2
    2 add dup PDFPageCount gt {                              %% If we have to draw an extra page, and this is it
      Verbose {(Drawing extra page ) print dup ==} if
      pop showpage                                           %% pop the spare loop and draw an empty page, stack: -save-
    }{
      Verbose {(Drawing page ) print dup ==} if
      0 0 PageWidth PageHeight rectclip
      pdfgetpage
      dup /Page exch store
      pdfshowpage_init     % <pagedict>
      draw_page_content
      showpage
    } ifelse
  restore                                                    %% restore back to the original CTM
} for

//runpdfend exec                                             %% End the PDF file

end                                                          %% our working dictioanry

这篇关于用于PDF的Ghostscript:如何将4页变成1页?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆