Java, Remove OLE headers from images stored as OLE Objects in access database
If you are using Java to access a MS Access database, and need to retrieve images stored in fields of type OLE Object, then this post can help you. When you insert images into OLE Object fields directly using the MS Access client, and you need to retrieve this image later to use in a desktop application or a web site, you will have a problem. The problem, is that the MS Access insert an OLE Header in the image file registered in database. So you will need to remove the OLE Header to use the image out of the Ms Access. The code below acomplishes this task.
This post is based on:
http://blogs.msdn.com/b/pranab/archive/2008/07/15/removing-ole-header-from-images-stored-in-ms-access-db-as-ole-object.aspx
I just ported the code to Java language.
The code:
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; /** * Class to remove OLE Header from images stored as OLE Object * @author Douglas.Pasqua */ public class OLEImage { // Map to store the initial block of different images formats private Map<String, String> imagesBeginBlock; public OLEImage() { // inicialize imagesBeginBlock = new HashMap<String, String>(); imagesBeginBlock.put("JPEG", "\u00FF\u00D8\u00FF"); // JPEG imagesBeginBlock.put("PNG", "\u0089PNG\r\n\u001a\n"); // PNG imagesBeginBlock.put("GIF", "GIF8"); // GIF imagesBeginBlock.put("TIFF", "II*\u0000"); // TIFF imagesBeginBlock.put("BMP", "BM"); // BMP } public byte[] getByteImgFromOLEInputStream(InputStream input, String imageFormat) { // get begin block identifier using imageFormat parameter String beginBlock = imagesBeginBlock.get(imageFormat); if(beginBlock == null) { throw new RuntimeException("Unsupported image format parameter value."); } try { byte[] b = toByteArray(input); String str = new String(b, "ISO-8859-1"); // identifying the initial position of the image int index = str.indexOf(beginBlock); if(index == -1) { throw new RuntimeException("Unable to determine image format."); } // removing the OLE Header byte[] buffer = new byte[b.length - index]; for(int i = 0, a = index; a < b.length; i++, a++) { buffer[i] = b[a]; } return buffer; } catch(IOException e) { e.printStackTrace(); } return null; } /** * Convert InputStream object to array of bytes * @throws IOException */ public byte[] toByteArray(InputStream is) throws IOException { int len; int size = 1024; byte[] buf; if (is instanceof ByteArrayInputStream) { size = is.available(); buf = new byte[size]; len = is.read(buf, 0, size); } else { ByteArrayOutputStream bos = new ByteArrayOutputStream(); buf = new byte[size]; while ((len = is.read(buf, 0, size)) != -1) { bos.write(buf, 0, len); } buf = bos.toByteArray(); } return buf; } }
Examples of Use
Using with JPEG, PNG and GIF images on Desktop Applications
Java has native support for JPG, PNG and GIF images. So theses images format will work well with ImageIcon class:
// the class to remove de OLE Headers from OLE Objects OLEImage oleImage = new OLEImage(); // get OLE object field from access database // ... // using with GIF format InputStream input = rs.getBinaryStream("oleGIF"); byte buffer[] = oleImage.getByteImgFromOLEInputStream(input, "GIF"); ImageIcon icon = new ImageIcon(buffer); // using with JPEG format InputStream input = rs.getBinaryStream("oleJPEG"); byte buffer[] = oleImage.getByteImgFromOLEInputStream(input, "JPEG"); ImageIcon icon = new ImageIcon(buffer); // using with PNG format InputStream input = rs.getBinaryStream("olePNG"); byte buffer[] = oleImage.getByteImgFromOLEInputStream(input, "PNG"); ImageIcon icon = new ImageIcon(buffer);
Using TIFF and BMP Images on Desktop Applications
Our OLEImage class supports removing OLE Headers for TIFF and BMP images format too. But java doesn’t support these image formats natively. So, you can’t use these formats directly with ImageIcon.
If you are developing for desktop, you will need a alternative method to support these formats. The following links can help you with this task:
http://stackoverflow.com/questions/593830/display-bmp-in-jlabel
http://stackoverflow.com/questions/1567398/showing-tiff-images-in-java
http://stackoverflow.com/questions/9634472/how-to-set-tif-image-to-imageicon-in-java
Using all Image Formats on Web Applications
You are free to use any image format when working in web enviroment. (If you need to send these images from Access database to client browser).
Thanks alot.
Sir i still have an exception like this: Unable to determine image format.
Your explanation is the best i have ever seen on OLE Objects with java. sir please help me out.
I have save PNG images in the ms Access directly and i n my java code iam using the following codes from your tutorial.
//// using with PNG format
//InputStream input = rs.getBinaryStream(“olePNG”);
//byte buffer[] = oleImage.getByteImgFromOLEInputStream(input, “PNG”);
//ImageIcon icon = new ImageIcon(buffer);
So i dont know the reason for that exception.
Sir please i need a quick reponse. thanks.
Nobies, thank you for the comment.
I updated the code in listing1 ! Was missing escaping characters. (probably lost int the last migration of my blog)
Try again and let me know if it worked.
good luck!