如何使用Java中的tEXt或iTXt块保存PNG?

我目前正在使用javax.imageio.ImageIO来编写PNG文件。 我想要包含一个tEXt块(实际上是这里列出的任何块),但是看不到这样做的方法。

通过com.sun.imageio.plugins.png.PNGMetadata的外观,它应该是可能的。

我应该非常感谢任何线索或答案。

M.

我在一些反编译后遇到的解决方案如下……

RenderedImage image = getMyImage(); Iterator iterator = ImageIO.getImageWritersBySuffix( "png" ); if(!iterator.hasNext()) throw new Error( "No image writer for PNG" ); ImageWriter imagewriter = iterator.next(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); imagewriter.setOutput( ImageIO.createImageOutputStream( bytes ) ); // Create & populate metadata PNGMetadata metadata = new PNGMetadata(); // see http://www.w3.org/TR/PNG-Chunks.html#C.tEXt for standardized keywords metadata.tEXt_keyword.add( "Title" ); metadata.tEXt_text.add( "Mandelbrot" ); metadata.tEXt_keyword.add( "Comment" ); metadata.tEXt_text.add( "..." ); metadata.tEXt_keyword.add( "MandelbrotCoords" ); // custom keyword metadata.tEXt_text.add( fractal.getCoords().toString() ); // Render the PNG to memory IIOImage iioImage = new IIOImage( image, null, null ); iioImage.setMetadata( metadata ); // Attach the metadata imagewriter.write( null, iioImage, null ); 

使用Java 1.6,我编写了Mike的代码

 Node document = domresult.getNode(); 

而不是他的路线

 Document document = dom.getResult(); 

而且,我建议添加一行

 writer.dispose() 

在完成工作之后,将释放作者所持有的任何资源。

试试Sixlegs Java PNG库( http://sofzh.miximages.com/java/pp 我们在JGraphX项目中这样做。 下载源代码并查看com.mxgraph.util.png包,在那里你会找到三个我们从Apache Batik源复制的编码类。 用法示例是saveXmlPng方法中的com.mxgraph.examples.swing.editor.EditorActions。 稍微编辑代码看起来像:

 mxPngEncodeParam param = mxPngEncodeParam .getDefaultEncodeParam(image); param.setCompressedText(new String[] { "mxGraphModel", xml }); // Saves as a PNG file FileOutputStream outputStream = new FileOutputStream(new File( filename)); try { mxPngImageEncoder encoder = new mxPngImageEncoder(outputStream, param); if (image != null) { encoder.encode(image); } } finally { outputStream.close(); } 

其中image是将形成.PNG的BufferedImage,而xml是我们希望放置在iTxt部分中的字符串。 “mxGraphModel”是该xml字符串的键(该部分包含一些键/值对),显然您用键替换它。

同样在com.mxgraph.util.png下,我们编写了一个非常简单的类,它可以在不处理整个图像的情况下提取iTxt。 您可以使用mxPngEncodeParam.setText而不是setCompressedText()对tEXt块应用相同的想法,但压缩文本部分允许相当大的文本部分。

我意识到这个问题很久以来就得到了回答,但是如果你想在没有进入“com.sun”层次结构的情况下这样做,这里是一个快速且非常丑陋的例子,因为我无法在其他任何地方找到这些文档。

 BufferedImage img = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB); // Create a DOM Document describing the metadata; // I've gone the quick and dirty route. The description for PNG is at // [http://sofzh.miximages.com/java/handle404"); writer.setOutput(ImageIO.createImageOutputStream(out)); writer.write(new IIOImage(img, null, meta)); out.close(); 

老问题,但…… PNGJ完全控制读写PNG块