views:

1617

answers:

7

Hi everyone,

I thought I would find a solution to this problem relatively easily, but here I am calling upon the help from ye gods to pull me out of this conundrum.

So, I've got an image and I want to store it in an XML document using Java. I have previously achieved this in VisualBasic by saving the image to a stream, converting the stream to an array, and then VB's xml class was able to encode the array as a base64 string. But, after a couple of hours of scouring the net for an equivalent solution in Java, I've come back empty handed. The only success I have had has been by:

import it.sauronsoftware.base64.*;
import java.awt.image.BufferedImage;
import org.w3c.dom.*;

...

      BufferedImage img;
      Element node;

      ...

      java.io.ByteArrayOutputStream os = new java.io.ByteArrayOutputStream();

      ImageIO.write(img, "png", os);

      byte[] array = Base64.encode(os.toByteArray());

      String ss = arrayToString(array, ",");

      node.setTextContent(ss);

      ...

  private static String arrayToString(byte[] a, String separator) {
    StringBuffer result = new StringBuffer();
    if (a.length > 0) {
        result.append(a[0]);
        for (int i=1; i<a.length; i++) {
            result.append(separator);
            result.append(a[i]);
        }
    }
    return result.toString();
  }

Which is okay I guess, but reversing the process to get it back to an image when I load the XML file has proved impossible. If anyone has a better way to encode/decode an image in an XML file, please step forward, even if it's just a link to another thread that would be fine.

Cheers in advance,

Hoopla.

+5  A: 

Apache Commons has a Base64 class that should be helpful to you:

From there, you can just write out the bytes (they are already in a readable format)

Eric Anderson
Cheers mate, that's a much neater package!
Hoopla
So why not mark this as the answer?
Eric Anderson
+1  A: 

Your arrayToString() method is rather bizarre (what's the point of that separator?). Why not simply say

String s = new String(array, "US-ASCII");

The reverse operation is

byte[] array = s.getBytes("US-ASCII");

Use the ASCII encoding, which should be sufficient when dealing with Base64 encoded data. Also, I'd prefer a Base64 encoder from a reputable source like Apache Commons.

Michael Borgwardt
Thanks Michael, admittedly I was clutching as straws and copied someone's example of how to convert the array without really thinking about it. Now using Apaches Commons. Cheers for advice
Hoopla
+1  A: 

After you get your byte array

byte[] array = Base64.encode(os.toByteArray());

use an encoded String :

String encodedImg = new String( array, "utf-8");

Then you can do fun things in your xml like

<binImg string-encoding="utf-8" bin-encoding="base64" img-type="png"><![CDATA[ encodedIImg here ]]></binImg>
Clint
+2  A: 

I've done something similar (encoding and decoding in Base64) and it worked like a charm. Here's what I think you should do, using the class Base64 from the Apache Commons project:

 //  ENCODING
 BufferedImage img = ImageIO.read(new File("image.png"));    
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 ImageIO.write(img, "png", baos);    
 baos.flush();
 String encodedImage = Base64.encodeToString(baos.toByteArray());
 baos.close(); // should be inside a finally block
 node.setTextContent(encodedImage); // store it inside node

 // DECODING
 String encodedImage = node.getTextContent();
 byte[] bytes = Base64.decode(encodedImage);
 BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));

Hope it helps.

JG
Still helping (Y)
Garis Suero
A: 

The basic problem is that you cannot have an arbitrary bytestream in an XML document, so you need to encode it somehow. A frequent encoding scheme is BASE64, but any will do as long as the recipient knows about it.

Thorbjørn Ravn Andersen
A: 

You don't need to invent your own XML data type for this. XML schema defines standard binary data types, such as base64Binary, which is exactly what you are trying to do.

Once you use the standard types, it can be converted into binary automatically by some parsers (like XMLBeans). If your parser doesn't handle it, you can find classes for base64Binary in many places since the datatype is widely used in SOAP, XMLSec etc.

ZZ Coder
A: 

With Java 6, you can use DatatypeConverter to convert a byte array to a Base64 string:

byte[] imageData = ...
String base64String = DatatypeConverter.printBase64Binary(imageData);

And to convert it back:

String base64String = ...
byte[] imageData = DatatypeConverter.parseBase64Binary(base64String);
vocaro