【发布时间】:2020-01-07 20:29:05
【问题描述】:
我有一个 java 程序,可以读取部分 postscript 文件以生成 postscript 和 PDF 报告。
如何创建要包含在报告中的彩色图像(例如徽标或横幅)资源?
已经有一个现有的彩色徽标作为后记文件。 需要弄清楚如何为新图像创建此类文件。 图片可以是以下任意一种格式:JPG、SVG 或 PNG。
作为一种解决方法,我已经尝试改进一个将 JPG 转换为具有 8 位分辨率的 postscript 资源的 java 应用程序。 但是无法弄清楚如何将其转换为具有 24 位分辨率的彩色 postscript 资源。
我尝试了许多将图像转换为“.PS”或“.EPS”文件的转换器,但它们都没有类似的代码,因此无法成功集成到 java 应用程序中(请参阅提供的 postscript 代码)。
以下彩色徽标的后记代码已显示在其中一份报告中。 java程序有什么方法可以读取图像(JPG或SVG)并将其转换为类似的代码:
/UniversityLogoResource {
newpath
0 84.2 moveto
474.8 84.2 lineto
474.8 0 lineto
0 0 lineto
0 84.2 lineto
closepath
1 1 1 setrgbcolor
fill
newpath
8.688 74.76 moveto
18.592 74.69 28.498 74.75 38.402 74.73 curveto
52.57 74.726 66.738 74.738 80.906 74.724 curveto
80.902 53.286 80.904 31.848 80.906 10.408 curveto
80.89 9.728 80.964 9.04 80.852 8.362 curveto
59.504 8.326 38.156 8.358 16.806 8.348 curveto
14.144 8.324 11.48 8.394 8.818 8.31 curveto
8.846 29.606 8.82 50.902 8.836 72.198 curveto
8.858 73.044 8.872 73.898 8.694 74.73 curveto
8.688 74.76 lineto
closepath
0 0.565 0.749 setrgbcolor
fill
newpath
8.694 74.73 moveto
8.872 73.898 8.858 73.044 8.836 72.198 curveto
8.82 50.902 8.846 29.606 8.818 8.31 curveto
8.636 8.506 8.55 8.736 8.564 9 curveto
8.568 30.598 8.566 52.196 8.564 73.794 curveto
8.584 74.11 8.626 74.422 8.694 74.73 curveto
closepath
0.275 0.608 0.69 setrgbcolor
fill
}
以下代码(替代解决方案)尝试将图像转换为 24 位分辨率的字节数组。是否可以将彩色图像转换为字节数组?:
private byte[] getImageBytesAt24BitsResolution() {
int[] pixels = new int[realWidth * realHeight];
PixelGrabber pixGrab = new PixelGrabber(image, 0, 0, realWidth, realHeight, pixels, 0, realWidth);
try {
pixGrab.grabPixels();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
int size = realWidth * realHeight;
byte[] data = new byte[size];
int datumPos = 0;
for (int y = 0; y < realHeight; y++) {
for (int x = 0; x < realWidth; x++) {
Color color = new Color(pixels[x + realWidth * y]);
int rgb = color.getRGB();
ColorModel cm = image.getColorModel();
Object pixel = cm.getDataElements(rgb, null);
data[datumPos] = ((byte[]) pixel)[0];
datumPos++;
}
}
return data;
}
下面的java代码用上面方法getImageBytesAt24BitsResolution()创建的字节数组imageBytes创建postscript资源文件:
byte[] rleBytes = PSDecoders.rleEncode(imageBytes);
// String[] asciiBytes = PSDecoders.ascii85Encode(rleBytes);
String[] asciiBytes = PSDecoders.hexEncode(rleBytes);
StringBuffer sb = new StringBuffer();
sb.append("%===============================================================\n");
sb.append("%%BeginResource: file " + (new File(mFileName).getName()) + " 1 0\n");
sb.append("/" + postscriptID +".form\n");
sb.append("<<\n");
sb.append("/FormType 1\n");
sb.append("/BBox[0 0 "+((int)Math.ceil(endWidth))+" "+((int)Math.ceil(endHeight))+"]\n");
sb.append("/Matrix[1 0 0 1 0 0]\n");
sb.append("/PaintProc{pop\n");
sb.append("/DeviceGray setcolorspace gsave\n");
sb.append(doubleFormat(endWidth)+" "+doubleFormat(endHeight)+" scale\n");
sb.append("<<\n");
sb.append("/Interpolate true\n");
sb.append("/ImageType 1\n");
sb.append("/Width "+realWidth+"\n");
sb.append("/Height "+realHeight+"\n");
sb.append("/ImageMatrix["+realWidth+" 0 0 -"+realHeight+" 0 "+realHeight+"]\n");
sb.append("/BitsPerComponent "+resolution.getBits()+"\n");
sb.append("/Decode[0 1]");
sb.append("/DataSource\n<");
for(String line : asciiBytes) {
sb.append(line);
sb.append("\n");
}
sb.append(">\n/RunLengthDecode filter\n>>\n");
sb.append("image grestore}\n>> def\n");
sb.append("% -- proc call\n");
sb.append("/" + postscriptID +" { % x y\n");
sb.append("gsave translate "+postscriptID+".form execform grestore\n");
sb.append("} def\n");
sb.append("%%EndResource\n");
【问题讨论】:
-
对于 SVG(这是一种矢量格式),您应该可以转换为 PS(作为低级操作)。许多工具已经这样做了。 PS 还支持嵌入的 JPEG 数据(DCTDecode 过滤器),这样您就不必先解码 JPEG。
-
@haraldK 谢谢你的回答。是的,我找到了一个名为“vectormagic”的工具,可以将 jpg 或 png 转换为 eps 矢量描述,我希望使用这个工具来解决这个问题。但是它不提供调整图像大小的功能,但我应该能够找到另一个工具或编写一些代码来实现这一点。谢谢。
-
@RobertLongson 感谢您提供有用的反馈。我已从问题正文中删除了该部分,并将其作为答案单独发布。
标签: java svg image-processing jpeg postscript