Как объединить два файла postscript вместе?
Я пытаюсь объединить два или несколько файлов postscript в один. Я пробовал конкатенацию, но она не работает, так как каждый файл postscript может иметь другой заголовок ресурса.
есть кто-нибудь делал это раньше? Существуют ли какие-либо библиотеки (коммерческие или с открытым исходным кодом)? Я не против библиотек C++, C# или даже Java.
редактировать Это большие файлы postscript (более 200 Мб) и их назначение только для цветной печати (не для онлайн просмотр.)
вывод
- ps2write не является ответом, как это не поддерживает DSC.
- pswrite как читатель pipitas правильно указал, производит выход L1. Это не soluton.
- использование pdfwrite является работоспособным. В этой опции мы преобразуем два ps в PDF, а затем преобразуем объединенный PDF в ps. Может возникнуть проблема с этим решением, поскольку во время преобразования может быть потеряна некоторая информация. К тому же дополнительные шаги преобразования требуют дополнительных ресурсов и времени.
- если нам не нужно просматривать выходной файл, объединение двух файлов postscript вместе со следующей строкой "false 0 startjob pop", вставленной между файлами, также является решением. (См. также этой ссылке)
В заключение, промежуточным решением для объединения двух файлов postscript является вариант 3 или 4.
6 ответов
вот пример командной строки Ghostscript, которая преобразует и объединяет два (или более) файла PostScript в один PDF за один раз:
gswin32c.exe ^
-o c:/path/to/output.pdf ^
-sDEVICE=pdfwrite ^
-dPDFSettings=/Screen ^
[...more desired parameters (optional)...] ^
/path/to/first.ps ^
/path/to/second.ps ^
/path/to/third.pdf
Edit: мой первый выстрел ложно предполагал входные файлы PDF. Конечно, он работает и с PostScript (или даже с сочетанием PS/PDF)... И выход также может быть PS.
конечно, вы также можете объединить различные входные файлы (PS, PDF или их сочетание) в один файл PostScript. Я включу еще несколько параметров настройки в следующую командную строку примера, которая увеличит резерв ОЗУ для Ghostscript на 800 Мб (при условии, что у вас есть машина с таким объемом памяти):
gswin32c.exe ^
-o c:/path/to/output.ps ^
-sDEVICE=ps2write ^
-c "800000000 setvmthreshold" ^
[...more desired parameters (optional)...] ^
/path/to/first.ps ^
/path/to/second.ps ^
/path/to/third.ps
вы должны указать, какое приложение создало ваши PostScripts и с какими настройками. Только тогда можно ожидать более конкретных советов. Ваш PostScripts may f.e. включите изображения hi-res (например, на 1200dpi), тогда как ваше устройство печати может быть способно только на 600dpi. В этом случае downsampling до 600dpi сделает файлы значительно меньше, не обязательно налагая штрафы за качество.
FYI я обнаружил, что это не работает правильно в одном случае - если какой-либо файл, но первый файл имеет ссылки в нем, они не будут правильными в конечном объединенном PDF. В частности, если сказать, что второй PDF имеет ссылку на свою вторую страницу, это будет ссылка на вторую страницу объединенного документа, что неправильно...
обратите внимание, что pdftk (который можно скачать бесплатно) получите ссылки справа.
GhostScript в Linux поставляется со сценарием оболочки под названием psmerge
(который установлен в "$@"'
if $running_under_some_shell;
# psmerge: merge PostScript files produced by same application and setup
# usage: psmerge [-oout.ps] file1.ps file2.ps ...
#
# Copyright (C) Angus J. C. Duggan 1991-1995
# See file LICENSE for details.
use strict;
$^W = 1;
my $prog = ( =~ m,([^/\]*)$,) ? : ;
my $outfile = undef;
usage() unless @ARGV;
while ($ARGV[0] =~ /^-/) {
$_ = shift;
if (/^-o(.+)/) {
$outfile = ;
} elsif (/^-t(horough)?$/) {
# This doesn't do anything, but we leave it for backward compatibility.
} else {
usage();
}
}
my $gs = find_gs();
if (defined $gs)
{
# Just invoke gs
$outfile = '/dev/stdout' unless defined $outfile;
exec +(qw(gs -q -dNOPAUSE -dBATCH -sDEVICE=pswrite),
"-sOutputFile=$outfile", '-f', @ARGV);
die "$prog: exec /usr/bin/gs failed\n";
}
else
{
warn +("$prog: /usr/bin/gs not found; falling back to old," .
" less functional behavior\n");
}
if (defined $outfile)
{
if (!close(STDOUT) || !open(STDOUT, ">$outfile")) {
print STDERR "$prog: can't open for output\n";
exit 1;
}
}
my $page = 0;
my $first = 1;
my $nesting = 0;
my @header = ();
my $header = 1;
my @trailer = ();
my $trailer = 0;
my @pages = ();
my @body = ();
my @resources = ();
my $inresource = 0;
while (<>) {
if (/^%%BeginFont:/ || /^%%BeginResource:/ || /^%%BeginProcSet:/) {
$inresource = 1;
push(@resources, $_);
} elsif ($inresource) {
push(@resources, $_);
$inresource = 0 if /^%%EndFont/ || /^%%EndResource/ || /^%%EndProcSet/;
} elsif (/^%%Page:/ && $nesting == 0) {
$header = $trailer = 0;
push(@pages, join("", @body)) if @body;
$page++;
@body = ("%%Page: ($page) $page\n");
} elsif (/^%%Trailer/ && $nesting == 0) {
push(@trailer, $_);
push(@pages, join("", @body)) if @body;
@body = ();
$trailer = 1;
$header = 0;
} elsif ($header) {
push(@trailer, $_);
push(@pages, join("", @body)) if @body;
@body = ();
$trailer = 1;
$header = 0;
} elsif ($trailer) {
if (/^%!/ || /%%EOF/) {
$trailer = $first = 0;
} elsif ($first) {
push(@trailer, $_);
}
} elsif (/^%%BeginDocument/ || /^%%BeginBinary/ || /^%%BeginFile/) {
push(@body, $_);
$nesting++;
} elsif (/^%%EndDocument/ || /^%%EndBinary/ || /^%%EndFile/) {
push(@body, $_);
$nesting--;
}
}
print @trailer;
sub find_gs
{
my $path = $ENV{'PATH'} || "";
my @path = split(':', $path);
foreach my $dir (@path)
{
return "$dir/gs" if -x "$dir/gs";
}
undef;
}
sub usage
{
print STDERR "Usage: $prog [-oout] file...\n";
exit 1;
}
мне удалось успешно объединить 100 + postscript-файлов (1500+ страниц) вместе, используя как %%Begin Document/ %%End Document, так и методы false 0 startjob pop.
проблема заключается в том, что при печати объединенного файла принтер приостанавливается на 20 - 45 секунд между объединенными файлами.
У кого-нибудь были подобные проблемы?
Как OP упоминалось в выводах вопроса, объединение файлов с строку
false 0 startjob pop
между ними должен сделать трюк. Так что в bash можно написать что-то вроде
mkdir merge
for ps in *.ps; do
cat $ps >> merge/output.ps
echo "false 0 startjob pop" >> merge/output.ps
done
однако, поскольку в вопросе также упоминается, что это полезно только для печати (или преобразования PDF), зритель, вероятно, не сможет отобразить все, кроме первого файла ps. Более подробную информацию можно найти здесь.