byte array to Image

19,519 views
Skip to first unread message

AgitoM

unread,
Sep 16, 2011, 6:54:18 AM9/16/11
to Google Web Toolkit
Hi all,

From a web service I am receiving a byte array that represents a
image.
I need to somehow squeeze this byte array into a image widget or
similar widget on my client side.

First I tried to convert the byte array to a base64 string:
String base64 = Base64Utils.toBase64(image);
base64 = "data:image/png;base64,"+base64;

This didn't work. The developer of the web service informed me that I
should not convert the byte array to a base64 string, and just use it
directly.

To test if the byte array represented a correct image, I saved the
byte array to a physical image:
InputStream in = new ByteArrayInputStream(image);
BufferedImage bImage = ImageIO.read(in);

File outputfile = new File("saved.png");
ImageIO.write(bImage, "png", outputfile);

This succesfully resulted in a physical image being created.

However I don't want to write the file and then send the URL to the
image widget on my client side.

Anybody have any suggestion about how I can get this byte array
squeezed into a image?
Or convert this byte array to a base64 string that does work?

Alexandre Dupriez

unread,
Sep 16, 2011, 9:38:14 AM9/16/11
to Google Web Toolkit
Modern browsers accept in URI the source of an image encoded in base64
and render it.

See http://stackoverflow.com/questions/2035811/send-bytearray-to-javascript

What did you do exactly? And why the web service's author told you
that you should not convert the picture in base64? Is the image
already encoded in base64?

Jens

unread,
Sep 16, 2011, 10:24:33 AM9/16/11
to google-we...@googlegroups.com
Base64Utils from GWT's source does not use the standard MIME characters when encoding data to Base64. So I think thats why the browser does not display the image. To verify this, you can try and search a MIME standard Base64 encoder, convert the byte array and put the base64 string into your data url.

Depending on what you want to do with the image you can try the following:
1.) Create a class BinaryData that holds the byte array and a mime type string (in your case "image/png")
2.) Write a plain servlet that reads data from your session based on a unique id and when its a BinaryData object returns the byte array with the correct mime type (and deletes the session entry to keep things clean).
3.) Use your existing servlet that fetches the byte array image, save it into a BinaryData instance and save that instance into your server session. Then return some unique id to your app and your app will use that id to fetch the data using the servlet from 2).

So basically your app asks your server to fetch an image from the web service. The server will do so and returns something like "193823903" as unique id. Now your app creates an Image widget and as URL it uses http://yourapp.com/service/binary?id=93823903. Your "binary" servlet will take the unique id, look it up in the session, found the BinaryData object with the byte array and returns the array with the specified mime type (image/png). The browser will display the image directly.
The only downside is that you can only access the image once (when you clean up your session when the image is requested) or you have to write a clean up thread so that your session doesn't get larger and larger.

Works great for me and I can use this for any kind of binary data like server side generated pdf's, sound files, images, etc.

-- J.

Alexandre Dupriez

unread,
Sep 16, 2011, 10:46:49 AM9/16/11
to google-we...@googlegroups.com
Hello Jens,

Why not converting into the right MIME type in one shot?

Thad

unread,
Sep 16, 2011, 11:15:36 AM9/16/11
to Google Web Toolkit
I believe that GWT (and browsers in general) use what the RFC calls
"Base 64 Encoding with URL and Filename Safe Alphabet" (see section 4
in http://www.faqs.org/rfcs/rfc3548.html).

You can find a Java Base64 class with URL-safe encoding at
http://iharder.sourceforge.net/current/java/base64/

On Sep 16, 9:38 am, Alexandre Dupriez <alexandre.dupr...@gmail.com>
wrote:
> Modern browsers accept in URI the source of an image encoded in base64
> and render it.
>
> Seehttp://stackoverflow.com/questions/2035811/send-bytearray-to-javascript

Jens

unread,
Sep 16, 2011, 11:27:28 AM9/16/11
to google-we...@googlegroups.com
How do you mean that? 

You either have to use a correct (browser compatible) base64 encoding or you need an URL that represents the data. If you want to support older browsers you would go with URL. Also I wouldn't send anything large in a base64 encoded way because base64 encoding makes things ~33% larger. Also I think IE8 only supports up to 32kb for a data URI scheme and only supports the data URI scheme for attributes that load images.

-- J.

Xi

unread,
Sep 16, 2011, 12:02:54 PM9/16/11
to Google Web Toolkit
Hi,

I've used http://sourceforge.net/projects/migbase64/ in my
application, to convert the byte array to a base64 string, which works
pretty well and efficient
My code is like : String base64 = "data:image/png;base64," +
Base64.encodeToString(bytes,false);
And at the client side, you just set the value into an image
element's "src" attribute.

But be careful, IE CAN NOT take charge of an image that bigger
than 32KB by using the "Base64" way.

Hope this can help you.

AgitoM

unread,
Sep 18, 2011, 5:10:05 AM9/18/11
to Google Web Toolkit
Hi All,

Thank you so much for the many replies.
Tried out the solution and library suggested by Xi just now, since his
solution was the easiest to verify.
It works.

After having downloaded this library:
http://sourceforge.net/projects/migbase64/

I convert the byte string like this:
String base64String = "data:image/png;base64," +
Base64.encodeToString(image,false);

Then simply use it at the client side like this:
Image image = new Image(base64String);

The image now displays. I think the base64 library I initially used
was not browser safe as Jens and Thad suggested.
Would have build a servlet as Jens suggested if it had not worked.

As for your question Alexandre, I don't know why the service developer
suggested I could not use base64.
Could have been inexperience on his behalf :-). Clearly base64 does
work.

On Sep 17, 12:02 am, Xi <chenx...@gmail.com> wrote:
> Hi,
>
>     I've usedhttp://sourceforge.net/projects/migbase64/in my

leandro borbosa

unread,
Sep 18, 2011, 3:44:10 PM9/18/11
to google-we...@googlegroups.com
I also needed this one.
Thx for sharing !

2011/9/18 AgitoM <karel...@gmail.com>
--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.


AgitoM

unread,
Sep 27, 2011, 6:56:12 AM9/27/11
to Google Web Toolkit
Decided to deal with the 32kb limit in Internet Explorer 8. (Internet
Explorer 9 is not a problem).
Dealt with the problem by creating a servlet that outputs the byte
array as a image.
I'm sending the ID of the image, in this case a map, to the servlet
using the GET method.

This is the code for the doGet operation for my dedicated
ImageServlet:

protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
response.setContentType("image/png");

if(request.getParameter("MapID") != null) {
int mapID = Integer.parseInt(request.getParameter("MapID"));

byte[] image = null;
try {
image = wsStub.getMapImage(mapID);
}
catch (Exception e) {
e.printStackTrace();
}

OutputStream out = response.getOutputStream();
out.write(image);
out.close();
}
}

On my RPC Servlet side, I simply return this as the "URL" of the
image:
("ImageServlet?MapID=" + mapID)

Code on the client side didn't change from what I earlier posted.

Magallo

unread,
Jun 4, 2012, 6:34:14 AM6/4/12
to google-we...@googlegroups.com
Excuse me Agito M, I'm intereseted in this solution. You said that "Code on the client side didn't change from what I earlier posted.". What do you mean? How do you call the servlet and how do you process the result and create the image client side? Please, could you possibly post some code to let me understand this? Thanks.

Anonymous

unread,
Oct 19, 2015, 8:29:27 AM10/19/15
to GWT Users
Hello Magallo

You can use a code like this:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    response.setContentType("image/png");

    if(request.getParameter("id") != null) {

       if(request.getParameter("id").equals("")) {

          response.sendError(500, "Bad request | Please provide an existing ...?id=X");

       }

      else {

        int mapID = Integer.parseInt(request.getParameter("id"));

        byte[] image = null;

        try {

           yourClientWrapper wrapper = yourDao.readById((long) mapID);

           image = wrapper.getYourImage();

        }

        catch (Exception e) {

           e.printStackTrace();

        }

         OutputStream out = response.getOutputStream();

         out.write(image);

         out.close();

      }

}

    else {

       response.sendError(500, "Bad request | Please provide an existing id with ...?id=X");

    }

}

On the client side: You just insert your Servlet-Url as the Image Resource (src-Attribute) like http://www.yourfancyurl.com/yourgwtapplication/servlet/imageGetter?id=31) and that's it. The servlet returns the image to the corresponding id without saving it to the disk.

I hope that this little explanation helps :)


Best regards


Reply all
Reply to author
Forward
0 new messages