ps2pdf: preserve page size

老子叫甜甜 提交于 2020-12-01 09:32:49

问题


I have myfile.ps with a vector image included. But when I run

ps2pdf myfile.ps

it seems that the output page size is A4: the vector image is too large and become cut away, so about one inch is lost.

The following pseudo-header is printed in the output PDF file, in addition to the original vector image:

PLOT SIZE:8.02x8.62Inches
Magnification:7354.21X

Is there any option or any way to convert the PS file to a PDF preserving the original paper size?


回答1:


I doubt your quoted 2 lines are really inside the PS file as quoted... Aren't they preceeded by % comment characters?

  • If they weren't preceeded by such characters, no PS interpreter would work, because they are no known PostScript operators.

  • If they are preceeded by such characters, the PS interpreter would simply ignore them, because... they are comments only! :-)

If you want to convert this PS file to PDF, it is better to run Ghostscript directly (ps2pdf is only a thin shell script wrapper around a Ghostscript command anyway):

gs -o myfile.pdf     \
   -sDEVICE=pdfwrite \
   -g5775x6207       \
   -dPDFFitPage      \
    myfile.ps

Explanation:

  1. -g... gives the medium size in pixels.
  2. An A4 page has a dimension of 595x842pt (PostScript points).
  3. 1 Inch is the same as 72 PostScript points.
  4. Ghostscript internally by default computes with a resolution of 720 pixels per inch when it comes to PDF output.
  5. Hence for PDF output 595x842pt == 5950x8420px.
  6. Hence for your case in question 8.02x8.62Inches ≈≈ 5775x6207px.



回答2:


If the input postscript has an EPS BoundingBox, this should preserve the page size:

ps2pdf -dEPSCrop <input.ps> <output.pdf>




回答3:


I am not allowed to comment, but I must warn everyone that all the current answers are vulnerable to malicious postscript files.

Using gs like this is VERY dangerous. ps2pdf internally uses the -dSAFER option which would, for example, prevent an untrusted postscript file from encrypting your files and rendering a pdf that demands a ransom payment from you for the decryption key! ALWAYS use -dSAFER!

While -o outputFile.pdf is nice, it is also undocumented (via man page or gs -h) as of version 9.23.

The below command works without worrying about the top being cut off like with the other solutions:

gs -sOutputFile=file.pdf -dNOPAUSE -dBATCH -sPAPERSIZE=a4 -sDEVICE=pdfwrite -dSAFER file.ps

-sPAPERSIZE=a4 is how the a4 paper size is specified.

to get the page size you can look for a line like the following:

%%PageBoundingBox:·12·12·583·830

and then use

gs -sOutputFile=file.pdf -dNOPAUSE -dBATCH -g583x830 -r72 -sDEVICE=pdfwrite -dSAFER file.ps

and it works perfectly.




回答4:


Based on @Kurt Pfeifle's answer I wrote this Perl script to do the task:

#! /usr/bin/env perl
use strict;
use warnings;

use Scalar::Util qw(looks_like_number);
use List::Util qw(all);


sub ps2pdf;
sub get_ps_headers;
sub get_media_size;
sub main;

# Run the program
main();


# Function: main
#
# Program's entry point.
#
sub main {
   for (@ARGV) {

      # check input file
      if(not -r) {
         print "WARN: Cannot read input file: $_\n";
         next;
      }

      # build PDF file name
      my $pdf = $_;
      $pdf =~ s/(\.e?ps)?$/.pdf/i;

      ps2pdf($_, $pdf);
   }
}


# Function: ps2pdf
#
# Converts a PostScript file to PDF format using GhostScript,
# keeping the medium size.
#
# Params:
#
#     $ps_file  - (string) Input [E]PS file name
#     $pdf_file - (string) Output PDF file name
#
sub ps2pdf {
   my ($ps_file, $pdf_file) = @_;
   my $cmd = "gs -q -sDEVICE=pdfwrite -dPDFFitPage ";

   # try to find the media size
   my ($width, $height) = get_media_size(get_ps_header($ps_file));

   # keep media size
   if(defined $height) {
      $cmd .= "-g${width}x${height} ";
   }

   # set input/output
   $cmd .= "-o $pdf_file $ps_file";

   print "Running: $cmd\n";

   system($cmd);
}


# Function: get_media_size
#
# Computes the size of a PostScript document in pixels,
# from the headers in the PS file.
#
# Params:
#
#     $hdr  - (hash ref) Parsed PS header values
#
# Returns:
#
#     On success: Two-element array holding the document's width and height
#     On failure: undef
#
sub get_media_size {
   my ($hdr) = @_;

   # we need the DocumentMedia header
   return undef if not defined $hdr->{DocumentMedia};

   # look for valid values
   my @values = split(/\s+/, $hdr->{DocumentMedia});
   return undef if scalar @values < 3;
   my ($width, $height) = @values[1, 2];

   return undef if not all { looks_like_number($_) } ($width, $height);

   # Ghostscript uses a default resolution of 720 pixels/inch,
   # there are 72 PostScript points/inch.
   return ($width*10, $height*10);
}


# Function: get_ps_header
#
#  Parses a PostScript file looking for headers.
#
# Params:
#
#     $ps_file - (string) Path of the input file
#
# Returns:
#
#     (hash ref) - As expected, keys are header names,
#     values are corresponding header values. A special key
#     named `version' is included for headers of the type
#     `PS-Adobe-3.0'
#
sub get_ps_header {
   my ($ps_file) = @_;
   my %head;

   open my $fh, "<$ps_file" or die "Failed to open $ps_file\n";
   while(<$fh>) {
      # look for end of header
      last if /^%%EndComments\b/;

      # look for PS version
      if(/^%!(\w+)/) {
         $head{version} = $1;
      }

      # look for any other field
      # Ex: %%BoundingBox: 0 0 1008 612
      elsif(/^%%(\w+)\s*:\s*(.*\S)/) {
         $head{$1} = $2;
      }

      # discard regular comments and blank lines
      elsif(/^\s*(%.*)?$/) {
         next;
      }

      # any other thing will finish the header
      else {
         last;
      }
   }

   return \%head;
}


来源:https://stackoverflow.com/questions/30128250/ps2pdf-preserve-page-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!