Ghostscript -- 将 PS 转换为 PNG、旋转和缩放
Ghostscript -- convert PS to PNG, rotate, and scale
我有一个应用程序可以创建非常漂亮的数据图,在 PostScript 中以字母大小和横向模式呈现。输入文件的示例位于 http://febo.com/uploads/blip.ps。 [注意:此图像在查看器中正确呈现,但 PNG 转换后图像出现横向。 ] 我需要将这些 PostScript 文件转换为按比例缩小并旋转 90 度的 PNG 图像以用于 Web 演示。
我想使用 ghostscript 而不是其他外部工具来执行此操作,因为转换程序将在 Windows 和 Linux 系统上使用,并且 gs 似乎是一个共同点。 (我正在创建一个带有 "PS2png" 函数的 perl 脚本,该函数将调用 gs,但我认为这与问题无关。)
我在网上搜索并花了几天时间尝试修改我找到的示例,但我没有尝试将 (a) 旋转、(b) 调整大小、(c) 保持宽高比和 (d) 避免剪裁。
我确实找到了一个将 "scale" 命令注入 postscript 流的示例,这似乎可以很好地在保持宽高比的同时将图像缩放到所需的大小。但是我找不到一种方法来旋转调整大小的图像,以便例如 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 with rotated coordinates, 以及我忘记的其他东西。 None 其中一些有效,但如果其中一些有效组合,我也不会感到惊讶。我只是没能找到它。
这是产生缩放但未旋转输出的核心代码:
## "$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 计算得出的。
我将感谢任何能告诉我实现这一目标的方法的人。谢谢!
更好的答案:
您在最初的研究中几乎成功了。只需在 gs
调用中设置方向:
... | gs ... -dAutoRotatePages=/None -c '<</Orientation 3>> setpagedevice' ...
比照。 discussion of setpagedevice in the Red Book, and ghostscript docs(就在第 6.2 节之前)
原答案:
除了"scale",你还需要"rotate"和"translate",不一定是这个顺序。
大概这些是单页 PostScript 文件?
如果你知道Postscript的边界框和png的尺寸,那么计算必要的变换就不会太费力了。这将是关于一行代码。您只需要确保将其注入正确的位置即可。
可以使用的简单 PostScript 文件。您只需要按某种顺序执行三个平移、缩放、旋转命令。剩下的就是演示是怎么回事了。
%!
% 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' -@ ...
多亏了 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 命令确实有效。
我有一个应用程序可以创建非常漂亮的数据图,在 PostScript 中以字母大小和横向模式呈现。输入文件的示例位于 http://febo.com/uploads/blip.ps。 [注意:此图像在查看器中正确呈现,但 PNG 转换后图像出现横向。 ] 我需要将这些 PostScript 文件转换为按比例缩小并旋转 90 度的 PNG 图像以用于 Web 演示。
我想使用 ghostscript 而不是其他外部工具来执行此操作,因为转换程序将在 Windows 和 Linux 系统上使用,并且 gs 似乎是一个共同点。 (我正在创建一个带有 "PS2png" 函数的 perl 脚本,该函数将调用 gs,但我认为这与问题无关。)
我在网上搜索并花了几天时间尝试修改我找到的示例,但我没有尝试将 (a) 旋转、(b) 调整大小、(c) 保持宽高比和 (d) 避免剪裁。
我确实找到了一个将 "scale" 命令注入 postscript 流的示例,这似乎可以很好地在保持宽高比的同时将图像缩放到所需的大小。但是我找不到一种方法来旋转调整大小的图像,以便例如 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 with rotated coordinates, 以及我忘记的其他东西。 None 其中一些有效,但如果其中一些有效组合,我也不会感到惊讶。我只是没能找到它。
这是产生缩放但未旋转输出的核心代码:
## "$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 计算得出的。 我将感谢任何能告诉我实现这一目标的方法的人。谢谢!
更好的答案:
您在最初的研究中几乎成功了。只需在 gs
调用中设置方向:
... | gs ... -dAutoRotatePages=/None -c '<</Orientation 3>> setpagedevice' ...
比照。 discussion of setpagedevice in the Red Book, and ghostscript docs(就在第 6.2 节之前)
原答案:
除了"scale",你还需要"rotate"和"translate",不一定是这个顺序。
大概这些是单页 PostScript 文件?
如果你知道Postscript的边界框和png的尺寸,那么计算必要的变换就不会太费力了。这将是关于一行代码。您只需要确保将其注入正确的位置即可。
可以使用的简单 PostScript 文件。您只需要按某种顺序执行三个平移、缩放、旋转命令。剩下的就是演示是怎么回事了。
%!
% 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' -@ ...
多亏了 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 命令确实有效。