0

I have an Image (type: java.awt.Image) in memory, I want to convert it to a Blob (type: java.sql.Blob) using jdk 1.7.

Everything I've been able to find on this subject uses streams and files. Surely I don't need to save this Image to a file before being able to convert it??

Not much to show here, but an example follows:

import java.sql.Blob; import java.awt.Image;

public GenericResponseType savePhoto(Image image)
{
       Connection conn = ds.getConnection();

       << some DB code and assembly of PreparedStatement >>

       Blob blob = conn.createBlob();

           << here's where the magic needs to happen I need to get the image parameter to blob >>
           // I've tried the following but doesn't quite work as it wants a RenderedImage
       // OutputStream os = blob.setBinaryStream(1);
       // ImageIO.write(parameters.getPhoto().getImage(), "jpg", os);


       pstmt.setBlob(4, blob);
     }

Some more detail (though I doubt it matters much) is that the above is generated using web services/JAX-WS from WSDL with an operation declared using MTOM. So it generates a signature with an Image being passed as a variable.

user3167187
  • 1
  • 1
  • 1
  • 2

2 Answers2

3

java.awt.Image is pretty simply. It does not provide any means by which the image can be written/saved nor does it provide any means to get access to underlying pixel data of the image.

The first step, is converting the java.awt.Image to something that ImageIO can support. This will allow you to write the image data out...

ImageIO requires a RenderedImage as it's primary image source. BufferedImage is the only implementation of this interface within the default libraries...

Unfortunately, there's no simply method for converting from one to the other. Fortunately, it's not to hard.

Image img = ...;

BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();

Basically, this just paints the original java.awt.Image onto the BufferedImage

Next, we need to save the image in some way so that it can produce a InputStream...

This is a little less then optimal, but gets the job done.

ByteArrayOutputStream baos = null;
try {
    baos = new ByteArrayOutputStream();
    ImageIO.write(bi, "png", baos);
} finally {
    try {
        baos.close();
    } catch (Exception e) {
    }
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

Basically, we write the image out to a ByteArrayOutputStream and the use the result to generate a ByteArrayInputStream

Now. If memory is an issue or the image is rather large, you can first write the image to a File and then simply read the File back in via some kind of InputStream instead...

Finally, we set the InputStream to the required column...

PreparedStatement stmt = null;
//...    
stmt.setBlob(parameterIndex, bais);

And Blob's your uncle...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thank you very much. I had seen the above as a possible approach but seemed like way too much work for something that on the surface seems like it should be very simple. I may have to just go with the file IO. – user3167187 Jan 07 '14 at 02:02
0

Try the following: (probably a much easier process, this was just what I found after a quick goolge and cannot guarantee it'll work - Mads answer looks much more credible).

  1. Get a BufferedImage (From this answer)

    BufferedImage buffered = new BufferedImage(scaleX, scaleY, TYPE);
    buffered.getGraphics().drawImage(image, 0, 0 , null);
    
  2. Get a byte array (From this answer)

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(buffered, "jpg", baos );
    byte[] imageInByte = baos.toByteArray();
    
  3. Save byte array as blob (From this answer) (but will should probably use a Prepared Statement)

    Blob blob = connection.createBlob();
    blob.setBytes(1, imageInByte);
    
Community
  • 1
  • 1
Java Devil
  • 10,629
  • 7
  • 33
  • 48