2009-04-06 7 views

Répondre

9

La solution que je frappe à bout d'un certain décompilation, va comme suit ...

RenderedImage image = getMyImage();   
Iterator<ImageWriter> 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); 
0

Essayez la bibliothèque Sixlegs Java PNG (http://sixlegs.com/software/png/). Il prétend avoir la prise en charge de tous les types de tronçons et gère le tronçonnage privé.

+0

est-ce pas seulement pour le décodage? – axel22

0

Nous le faisons dans le projet JGraphX. Téléchargez le code source et jetez un oeil dans le paquet com.mxgraph.util.png, vous y trouverez trois classes pour l'encodage que nous avons copiées à partir des sources Apache Batik. Un exemple d'utilisation se trouve dans com.mxgraph.examples.swing.editor.EditorActions dans la méthode saveXmlPng. édité légèrement le code ressemble:

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(); 
} 

où l'image est le BufferedImage qui forme le .PNG et xml est la chaîne que nous souhaitons placer dans la section iTxt. "mxGraphModel" est la clé de cette chaîne xml (la section comprend un certain nombre de paires clé/valeur), évidemment vous la remplacez par votre clé. De plus, sous com.mxgraph.util.png, nous avons écrit une classe très simple qui extrait l'iTxt sans traiter l'image entière. Vous pouvez appliquer la même idée pour le bloc tEXt en utilisant mxPngEncodeParam.setText au lieu de setCompressedText(), mais la section de texte compressé autorise des sections de texte plus grandes.

0

Je réalise que cette question est depuis longtemps répondue, mais si vous voulez le faire sans plonger dans la hiérarchie "com.sun", voici un exemple rapide et très laid comme je ne pouvais pas trouver cela documenté ailleurs.

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://download.oracle.com/javase/1.4.2/docs/api/javax/imageio/metadata/doc-files/png_metadata.html][1] 

Calendar c = Calendar.getInstance(); 
String xml = "<?xml version='1.0'?><javax_imageio_png_1.0><tIME year='"+c.get(c.YEAR)+"' month='"+(c.get(c.MONTH)+1)+"' day='"+c.get(c.DAY_OF_MONTH)+"' hour='"+c.get(c.HOUR_OF_DAY)+"' minute='"+c.get(c.MINUTE)+"' second='"+c.get(c.SECOND)+"'/><pHYs pixelsPerUnitXAxis='"+11811+"' pixelsPerUnitYAxis='"+11811+"' unitSpecifier='meter'/></javax_imageio_png_1.0>"; 
DOMResult domresult = new DOMResult(); 
TransformerFactory.newInstance().newTransformer().transform(new StreamSource(new StringReader(xml)), domresult); 
Document document = dom.getResult(); 

// Apply the metadata to the image 
ImageWriter writer = (ImageWriter)ImageIO.getImageWritersBySuffix("png").next(); 
IIOMetadata meta = writer.getDefaultImageMetadata(new ImageTypeSpecifier(img), null); 
meta.setFromTree(meta.getMetadataFormatNames()[0], document.getFirstChild()); 
FileOutputStream out = new FileOutputStream("out.png"); 
writer.setOutput(ImageIO.createImageOutputStream(out)); 
writer.write(new IIOImage(img, null, meta)); 
out.close(); 
1

Utilisation de Java 1.6, je modifié le code de Mike à

Node document = domresult.getNode(); 

au lieu de sa ligne

Document document = dom.getResult(); 

De plus, je vous suggère d'ajouter une ligne

writer.dispose() 

après le travail a été fait, de sorte que tout r Les ressources détenues par l'écrivain sont libérées.

0

question ancienne, mais ... PNGJ donne un contrôle complet pour la lecture et l'écriture des morceaux PNG

Questions connexes