【问题标题】:How to convert image to postscript shape如何将图像转换为 postscript 形状
【发布时间】: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


【解决方案1】:

您不能在 PostScript 程序中嵌入 SVG 或 PNG 图像,因为 PostScript 不包含对这些格式的任何支持。您需要先将它们解码为简单的光栅位图。

您引用的徽标未使用图像。它通过绘制一系列形状并填充它们来绘制徽标。它是矢量描述而不是图像。

可以将光栅图像转换为一系列矩形填充;依次获取每个图像样本,计算其在输出设备上的位置(和大小),在给定位置绘制一个大小相同的矩形,并用样本的颜色值填充它。这将产生一个绝对巨大的输出文件,渲染速度非常慢。

最好将图像数据包含为图像。要在 PostScript 中绘制图像,请使用 image 运算符,它有两种形式。我建议您使用运算符的字典形式。图像运算符在 PostScript 语言参考手册(第 3 版)的第 607 页中定义,并在同一参考的第 288 页开始的第 4.10 节中进行了详细说明。

基本上,您需要设置图像字典,其中包含许多参数,Width、Height、BitsPerComponent、一个从(通常是当前文件)读取图像数据的 DataSource 和一个定义最终图像大小和位置的 ImageMatrix用户空间。现在对于 JPEG 图像,您可以简单地插入压缩数据流并将 DataSource 指定为使用 DCTDecode 过滤器。需要对其他图像格式进行解码,并将图像数据作为原始样本插入,或者,如果需要考虑大小,则使用可用的 PostScript 过滤器(如 Flate)和 DataSource 提供的适当解码过滤器进行压缩。

例如,这里是传统的火鸡图像,在级别 2 中定义:

%!
50 10 translate  % Locate lower-left corner of square

/DrawTurkey {
0 setgray
<<
/ImageType 1
/Width 24
/Height 23
/ImageMatrix [.24 0 0 .23 0 0]
/BitsPerComponent 1
/Decode [1 0]
/MultipleDataSources false
/DataSource < 003B00 002700 002480 0E4940
114920 14B220 3CB650 75FE88
17FF8C 175F14 1C07E2 3803C4
703182 F8EDFC B2BBC2 BB6F84
31BFC2 18EA3C 0E3E00 07FC00
03F800 1E1800 1FF800 >
>> imagemask
} def

% Draw the turkey upright

24 2 div 23 2 div [.24 0 0 .23 0 0] transform 
exch (centre at x = ) print == ( y = ) print ==

0.5 setgray
0 0 100 100 rectfill
0 1 0 setrgbcolor
0 0 moveto 0 100 lineto stroke
0 0 1 setrgbcolor
0 0 moveto 100 0 lineto stroke
1 0 0 setrgbcolor
0 0 moveto 100 100 lineto stroke
DrawTurkey

showpage

请注意,此程序将图像数据嵌入十六进制字符串,如果图像数据超过 64Kb,您将无法这样做。

【讨论】:

  • 非常感谢您的回答。我在问题中提到的替代解决方案正是尝试按照您的建议进行操作。我已使用用于生成此文件的代码更新了问题。它适用于灰色图像。但是我无法创建彩色图像。我认为数据源(嵌入为十六进制字符串的图像数据)和传递给图像字典的参数存在问题。我想我将深入研究 postscript 参考手册,以使其特别适用于您提到的部分。再次感谢您的帮助。
【解决方案2】:

最终通过使用名为“vectormagic”的 JPG 到 EPS 转换器创建彩色图像的矢量描述来解决此问题。然后开发了一个函数,该函数将使用“翻译”(指定徽标的位置)和“缩放”(调整徽标的大小)命令加载此矢量描述。还需要用 'gsave' 和 'grestore' 将其包围,以避免报告中其他元素的对齐问题:

/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
......
......
%full vector description retrieved via 'vectormagic' converter 
....
398.59 122.99 402.63 123.16 405.76 123.96 curveto
closepath
1.000 0.996 1.000 setrgbcolor
fill
} def

/DrawUniversityLogo {  
/translateX exch def
/translateY exch def
/scaleX exch def
/scaleY exch def


gsave

translateX translateY translate
scaleX scaleY scale
UniversityLogoResource

grestore

} def

感谢所有支持解决此问题的人。

【讨论】:

    猜你喜欢
    • 2015-05-05
    • 2020-05-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 2017-10-08
    • 2017-02-18
    相关资源
    最近更新 更多