I'm trying to inline (embed) an image in a JEditorPane from a file such as:
<img src="data:image/gif;utf-8,data...">
But I'm struggling with the code.
So far I have (assuming a gif file):
try
{
File imageFile = new File("C:\\test\\testImage.gif");
File htmlFile = new new File("C:\\test\\testOutput.html");
byte[] imageBytes = Files.toByteArray(imageFile);
String imageData = new String(imageBytes, "UTF-8");
String html = "<html><body><img src=\"data:image/gif;utf-8," + imageData + "\"></body></html>";
FileUtils.writeStringToFile(htmlFile, htmlText);
} catch (Exception e) {
e.printStackTrace();
}
This does create a file but the image is invalid. I'm sure I'm not converting the image the proper way...
JEditorPane (and Java HTML rendering in general) does not support Base64 encoded images.
Of course 'does not' != 'could not'.
The thing is, you'd need to create (or adjust) an EditorKit can have new elements defined. An e.g. is seen in the AppletEditorKit. You'd need to look for HTML.tag.IMG - it is is a standard image, call the super functionality, else use this source (or similar) to convert it to an image, then embed it.
Related
Does anyone know how image file can be easily converted into PDF format. What I need is to get the image from database and display it on the screen as PDF. What am I doing wrong? I tried to use iText but with no results.
My code:
StreamResource resource = file.downloadFromDatabase();//get file from db
Document converToPdf=new Document();//Create Document Object
PdfWriter.getInstance(convertToPdf, new FileOutputStream(""));//Create PdfWriter for Document to hold physical file
convertToPdf.open();
Image convertJpg=Image.getInstance(resource); //Get the input image to Convert to PDF
convertToPdf.add(convertJpg);//Add image to Document
Embedded pdf = new Embedded("", convertToPdf);//display document
pdf.setMimeType("application/pdf");
pdf.setType(Embedded.TYPE_BROWSER);
pdf.setSizeFull();
Thanks.
You're not using iText correctly:
You never close your writer, so the addition of the image never gets written to the outputstream.
You pass an empty string to your FileOutputStream. If you want to keep the pdf in memory, use a ByteArrayOutputStream. If not, define a temporary name instead.
You pass your Document object, which is a iText-specific object to your Embedded object and treat it like a file. It is not a pdf-file or byte[]. You'll probably want to pass either your ByteArrayOutputStream or read the temp file as a ByteArrayOutputStream into memory and pass that to Embedded.
Maybe someone will use (Vaadin + iText)
Button but = new Button("FV");
StreamResource myResource = getPDFStream();
FileDownloader fileDownloader = new FileDownloader(myResource);
fileDownloader.extend(but);
hboxBottom.addComponent( but );
private StreamResource getPDFStream() {
StreamResource.StreamSource source = new StreamResource.StreamSource() {
public InputStream getStream() {
// step 1
com.itextpdf.text.Document document = new com.itextpdf.text.Document();
// step 2
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
com.itextpdf.text.pdf.PdfWriter.getInstance(document, baos);
// step 3
document.open();
document.add(Chunk.NEWLINE); //Something like in HTML :-)
document.add(new Paragraph("TEST" ));
document.add(Chunk.NEWLINE); //Something like in HTML :-)
document.newPage(); //Opened new page
//document.add(list); //In the new page we are going to add list
document.close();
//file.close();
System.out.println("Pdf created successfully..");
} catch (DocumentException ex) {
Logger.getLogger(WndOrderZwd.class.getName()).log(Level.SEVERE, null, ex);
}
ByteArrayOutputStream stream = baos;
InputStream input = new ByteArrayInputStream(stream.toByteArray());
return input;
}
};
StreamResource resource = new StreamResource ( source, "test.pdf" );
return resource;
}
I'm working now for e-book reader written in Java. Primary file type is fb2 which is XML-based type.
Images inside these books stored inside <binary> tags as a long text line (at least it looks like text in text editors).
How can I transform this text in actual pictures in Java? For working with XML I'm using JDOM2 library.
What I've tried does not produce valid pictures (jpeg files):
private void saveCover(Object book) {
// Necessary cast to process with book
Document doc = (Document) book;
// Document root and namespace
Element root = doc.getRootElement();
Namespace ns = root.getNamespace();
Element binaryEl = root.getChild("binary", ns);
String binaryText = binaryEl.getText();
File cover = new File(tempFolderPath + "cover.jpeg");
try (
FileOutputStream fileOut = new FileOutputStream(cover);
BufferedOutputStream bufferOut = new BufferedOutputStream(
fileOut);) {
bufferOut.write(binaryText.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
The image content is specified as being base64 encoded (see: http://wiki.mobileread.com/wiki/FB2#Binary ).
As a consequence, you have to take the text from the binary element and decode it in to binary data (in Java 8 use: java.util.base64 and this method: http://docs.oracle.com/javase/8/docs/api/java/util/Base64.html#getDecoder-- )
If you take the binaryText value from your code, and feed it in to the decoder's decode() method you should get the right byte[] value for the image.
Im trying to add a image from a URL address to my pdf. The code is:
Image image=Image.getInstance("http://www.google.com/intl/en_ALL/images/logos/images_logo_lg.gif");
image.scaleToFit((float)200.0, (float)49.0);
paragraph.add(image);
But it does not work. What can be wrong?
This is a known issue when loading .gif from a remote location with iText.
A fix for this would be to download the .gif with Java (not via the getInstance method of iText's Image class) and to use the downloaded bytes in the getInstance method of the Image class.
Edit:
I went ahead and fixed remote gif loading in iText, it is included from iText 5.4.1 and later.
Adding Image into Itext PDF is not possible through URL .
Only way to add image in PDF is download all images in to local directory and apply below code
String photoPath = Environment.getExternalStorageDirectory() + "/abc.png";
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
final Bitmap b = BitmapFactory.decodeFile(photoPath, options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap.createScaledBitmap(b, 10, 10, false);
b.compress(Bitmap.CompressFormat.PNG, 30, stream);
Image img = null;
byte[] byteArray = stream.toByteArray();
try {
img = Image.getInstance(byteArray);
} catch (BadElementException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The way you have used to add images to IText PDF is the way that is used for adding local files, not URLs.
For URLs, this way will solve the problem.
String imageUrl = "http://www.google.com/intl/en_ALL/"
+ "images/logos/images_logo_lg.gif";
Image image = Image.getInstance(new URL(imageUrl));
You may then proceed to add this image to some previously open document, using document.add(image).
For further reference, please visit the [Java IText: Image docs].
I'm trying to generate an SVG image and then transcode it to PNG using Apache Batik. However, I end up with an empty image and I can't see why.
I use the Document from SVGDomImplementation as the base for my transcoding (to avoid writing the SVG to disk and loading it again). Here's an example:
DOMImplementation domImpl = SVGDOMImplementation.getDOMImplementation();
String namespace = SVGDOMImplementation.SVG_NAMESPACE_URI;
Document document = domImpl.createDocument(namespace, "svg", null);
//stuff that builds SVG (and works)
TranscoderInput transcoderInput = new TranscoderInput(svgGenerator.getDOMFactory());
PNGTranscoder transcoder = new PNGTranscoder();
transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, new Float(svgWidth));
transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, new Float(svgHeight));
try {
File temp = File.createTempFile(key, ".png");
FileOutputStream outputstream = new FileOutputStream(temp);
TranscoderOutput output = new TranscoderOutput(outputstream);
transcoder.transcode(transcoderInput, output);
outputstream.flush();
outputstream.close();
name = temp.getName();
} catch (IOException ioex) {
ioex.printStackTrace();
} catch (TranscoderException trex) {
trex.printStackTrace();
}
My problem is that the resulting image is empty and I can't see why. Any hints?
I think it depends on how you're creating the SVG document. What are you using svgGenerator for (which I assume is an SVGGraphics2D)?
TranscoderInput transcoderInput = new TranscoderInput(svgGenerator.getDOMFactory());
If you've built up the SVG document in document, then you should pass it to the TranscoderInput constructor.
This page has an example of rasterizing an SVG DOM to a JPEG.
I am currently using javax.imageio.ImageIO to write a PNG file. I would like to include a tEXt chunk (and indeed any of the chunks listed here), but can see no means of doing so.
By the looks of com.sun.imageio.plugins.png.PNGMetadata it should be possible.
I should be most grateful for any clues or answers.
M.
The solution I struck upon after some decompilation, goes as follows ...
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 );
I realise this question is long since answered, but if you want to do it without dipping into the "com.sun" hierarchy, here's an quick and very ugly example as I couldn't find this documented anywhere else.
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();
Using Java 1.6, I edited Mike's code to
Node document = domresult.getNode();
instead of his line
Document document = dom.getResult();
Moreover, I'd suggest to add a line
writer.dispose()
after the job has been done, so that any resources held by the writer are released.
We do this in the JGraphX project. Download the source code and have a look in the com.mxgraph.util.png package, there you'll find three classes for encoding that we copied from the Apache Batik sources. An example of usage is in com.mxgraph.examples.swing.editor.EditorActions in the saveXmlPng method. Slightly edited the code looks like:
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();
}
Where image is the BufferedImage that will form the .PNG and xml is the string we wish to place in the iTxt section. "mxGraphModel" is the key for that xml string (the section comprises some number of key/value pairs), obviously you replace that with your key.
Also under com.mxgraph.util.png we've written a really simple class that extracts the iTxt without processing the whole image. You could apply the same idea for the tEXt chunk using mxPngEncodeParam.setText instead of setCompressedText(), but the compressed text section does allow for considerable larger text sections.
Try the Sixlegs Java PNG library (http://sixlegs.com/software/png/).
It claims to have support for all chunk types and does private chunk handling.
Old question, but... PNGJ gives full control for reading and writing PNG chunks