我有一个应用程序,可以创建以PostScript呈现的非常漂亮的数据图,并具有字母大小和横向模式。输入文件的示例位于http://febo.com/uploads/blip.ps。 [注意:此图像可在查看器中正确呈现,但PNG转换会随图像一起出现。 ]我需要将这些PostScript文件转换为PNG图片,然后将其缩小并旋转90度以进行Web演示。
我想使用ghostscript而不使用其他外部工具来执行此操作,因为转换程序将同时在Windows和Linux系统上使用,并且gs似乎是一个共同点。 (我正在创建一个带有“ PS2png”函数的perl脚本,该函数将调用gs,但我认为这与问题无关。)
我已经在网上搜索并花了几天的时间来尝试修改我发现的示例,但是我没有尝试过(a)旋转,(b)调整大小,(c)保持宽高比的组合和(d)避免削波。
我确实找到了一个向后记流中注入“缩放”命令的示例,并且在保持纵横比的同时将图像缩放到所需大小似乎效果很好。但是我找不到旋转尺寸调整后的图像的方法,以使例如601 x 792点(2504 x 3300像素)的后记输入变为800 x 608像素png输出。
我正在寻找可以传递给gs命令行的ghostscript / postscript fu。
我尝试使用-dFIXEDMEDIA,-dFitPage,-dAutoRotatePages = / None或/ All,-c“ <> setpagedevice”的各种组合的gs命令行,更改-dDISPLAYWIDTHPOINTS和-dDISPLAYHEIGHTPOINTS,-g [width] x [height],带有旋转坐标的-dUseCropBox以及其他我忘记的东西。这些方法都没有效果,但是如果其中一些方法可以魔术组合,也不会令我感到惊讶。我只是找不到它。
以下是产生缩放但未旋转的输出的核心代码:
## "$molps" is the input ps file read to a variable
## insert the PS "scale" command
$molps = $sf . " " . $sf . " scale\n" . $molps;
$gsopt1 = " -r300 -dGraphicsAlphaBits=4 -dTextAlphaBits=4";
$gsopt1 = $gsopt1 . " -dDEVICEWIDTHPOINTS=$device_width_points";
$gsopt1 = $gsopt1 . " -dDEVICEHEIGHTPOINTS=$device_height_points";
$gsopt1 = $gsopt1 . " -sOutputFile=" . $outfile;
$gscmd = "gs -q -sDEVICE=pnggray -dNOPAUSE -dBATCH " . $gsopt1 . " - ";
system("echo \"$molps\" \| $gscmd");
$ device_width_points和$ device_height_points是通过获取原始图像大小并应用缩放因子$ sf来计算的。 我将感谢任何能够向我展示实现此目标的方法的人。谢谢!
答案 0 :(得分:1)
更好的答案:
您几乎在最初的研究中就掌握了它。只需在gs
调用中设置方向:
... | gs ... -dAutoRotatePages=/None -c '<</Orientation 3>> setpagedevice' ...
cf。 《红皮书》中的discussion of setpagedevice和ghostscript docs(在6.2节之前)
原始答案:
除了“缩放”外,您还需要“旋转”和“翻译”,而不必按此顺序。
大概是单页PostScript文件吗?
如果您知道Postscript的边框和png的尺寸,那么计算必要的转换就不会太费力。大约只有一行代码。您只需要确保将其注入正确的位置即可。
一个简单的PostScript文件可以使用。您只需要按顺序排列三个translate,scale,rotate命令。其余的用于演示正在发生的事情。
%!
% function to define a 400x400 box outline, origin at 0,0 (bottom left)
/box { 0 0 moveto 0 400 lineto 400 400 lineto 400 0 lineto closepath } def
box clip % pretend the box is our bounding box
clippath stroke % draw initial black bounding box
(Helvetica) findfont 50 scalefont setfont % setup a font
% draw box, and show some text @ 100,100
box stroke
100 100 moveto (original) show
% try out some transforms
1 0 0 setrgbcolor % red
.5 .5 scale
box stroke
100 100 moveto (+scaled) show
0 1 0 setrgbcolor % green
300 100 translate
box stroke
100 100 moveto (+translated) show
0 0 1 setrgbcolor % blue
45 rotate
box stroke
100 100 moveto (+rotated) show
showpage
可能会像这样将计算出的变换插入gs
命令行中:
... | gs ... -c '1 2 scale 3 4 translate 5 6 rotate' -@ ...
答案 1 :(得分:1)
多亏了JHNC,我认为我现在已经舔过了,为了后代的利益,这是行之有效的。 (请支持JHNC,而不是此答案。)
## code to determine original size, scaling factor, rotation goes above
my $device_width_points;
my $device_height_points;
my $orientation;
if ($rotation) {
$orientation = 3;
$device_width_points = $ytotal_png_pt;
$device_height_points = $xtotal_png_pt;
} else {
$orientation = 0;
$device_width_points = $xtotal_png_pt;
$device_height_points = $ytotal_png_pt;
}
my $orientation_string =
" -dAutoRotatePages=/None -c '<</Orientation " .
$orientation . ">> setpagedevice'";
## $ps = .ps file read into variable
## insert the PS "scale" command
$ps = $sf . " " . $sf . " scale\n" . $ps;
$gsopt1 = " -r300 -dGraphicsAlphaBits=4 -dTextAlphaBits=4";
$gsopt1 = $gsopt1 . " -dDEVICEWIDTHPOINTS=$device_width_points";
$gsopt1 = $gsopt1 . " -dDEVICEHEIGHTPOINTS=$device_height_points";
$gsopt1 = $gsopt1 . " -sOutputFile=" . $outfile;
$gsopt1 = $gsopt1 . $orientation_string;
$gscmd = "gs -q -sDEVICE=pnggray -dNOPAUSE -dBATCH " . $gsopt1 . " - ";
system("echo \"$ps\" \| $gscmd");
我遇到的问题之一是某些选项显然不能很好地配合使用-例如,我尝试使用-g选项以像素为单位设置输出大小,但在这种情况下旋转无效。而是使用DEVICE ... POINTS命令起作用了。