Display a Blob as an image in a Vaadin grid

I’m trying to follow
this example

I have a blob image in a mysql database, and I’m trying to display it in a grid. I think it’s a MMOBJS.LNL_BLOB if that makes a difference, but it’s my first time trying to work this type of thing.

[code]
Class.forName(“net.sourceforge.jtds.jdbc.Driver”);
con = DriverManager.getConnection(“jdbc:jtds:sqlserver://SERVERNAME;instance=SQLEXPRESS”,“username”,“password”);
String sql = “SELECT firstName, lastName, blob from table”;
stmt = con.createStatement( );
rs = stmt.executeQuery(sql);
//Add in all info
while (rs.next()){
Blob b = rs.getBlob(3);
byte bdata = b.getBytes(1, (int) b.length());
String x = Base64.getEncoder().encodeToString(bdata);

            ExternalResource e = new ExternalResource("data:image/png;base64,"+x);
            
            beanList.addBean(new Bean(rs.getString(1), //FirstName
                    rs.getString(2), //Last Name
                    e)); //blob
            }
        
    } catch (SQLException | ClassNotFoundException e) {
        e.printStackTrace();
    }finally{
        try { con.close();    } catch (SQLException e) {}
        try { rs.close();    } catch (SQLException e) {}
        try { stmt.close();    } catch (SQLException e) {}
    } // End finally (try catch)

    Grid g = new Grid(contractorsList);
    g.getColumn("blob").setRenderer(new ImageRenderer());
   
    addComponent(g);

[/code]I did get some images, but they were nothing like what they were suppose to look like. Just blank black squares. If I try to decode as jpg, I get a broken image placeholder.

So the basic idea is I obtain the Blob from the resultset, then convert it to a Base64 string like the example. After, I wrap it as an External resource, and then have Vaadin render it.

I think I’m having trouble with how to convert the blob image, whether I’m converting it right or not… or is there a workaround to this that I don’t know about?

The ImageRenderer of the Framework seems to be implemented in a such way that it takes ImageResource as an input. If your image is some sort of raw data as you mentioned (Base64 encoded string), it wont work directly. You need to implement from your data to ImageResource converter also. And then add both the converter and renderer to the column.

So I need to convert the BLOB image into an actual image (.jpg, .png, etc) then ImageRenderer will work.

Or I need to figure out how to write a converter for ImageResource?

Actually both and it is even more complicated than that. Standard GWT Image component (which is used also in ImageRenderer) needs URL to images. The GWT Image component is quite old and supports even very old browsers, which are not capbable of showing inlined Base64-encoded images or image in HTML canvas. So in your case one alternative would be to convert images to jpg/png/gif into a temporary resource folder (image cache) and map ImageResource’s which have URL’s pointing to them. Maybe instead of Converter you could have DTO bean which have the ImageResources instead of BLOB’s and have BLOB’s to Image Cache handling somewhere else in your business logic. If you do the whole thing in Converter the result may be slow and you would be doing BLOB → ImageFile conversion too often, which slows performance.

There is BLOB image renderer now in Grid Renderers Collection Add-On. (Note it wont work on IE8)

https://vaadin.com/directory#!addon/grid-renderers-collection-for-vaadin7

Thank you! This is so helpful!