Wednesday, March 19, 2014

Saving an image in Cassandra BLOB field

We had an occasion today to be able to store images in a blob field of a Cassandra tables.  More to the point I needed to extract it and send it from a java servlet to a web browser as an image.   The code for storing the image is quit easy but there is a small gotcha when retrieving it.   So, suppose we have a table that looks something like:

String CreateTweetTable = "CREATE TABLE if not exists Messages ("+
                "user varchar,"+
                " interaction_time timeuuid,"+
                " tweet varchar,"+
                " image blob," +
                " imagelength int,"+
                " PRIMARY KEY (user,interaction_time)"+
                ") WITH CLUSTERING ORDER BY (interaction_time DESC);";

Our image will be in the blob field and we also store the size of the image for reference. We can load a picture from a file on the local machines hard disk like this:

FileInputStream fis=new FileInputStream("/Users/Administrator/Desktop/mystery.png");
byte[] b= new byte[fis.available()+1];
int length=b.length;
fis.read(b);

We now need to convert the byte array into a bytebuffer:

ByteBuffer buffer =ByteBuffer.wrap(b);

Writing the record becomes simply:

 PreparedStatement ps = session.prepare("insert into Messages ( image, user, interaction_time,imagelength) values(?,?,?,?)");
BoundStatement boundStatement = new BoundStatement(ps);
session.execute(  boundStatement.bind( buffer, "Andy",  convertor.getTimeUUID(),length));


Getting the image back is simple.  Use a Select to get the result set:

PreparedStatement ps = session.prepare("select user,image,imagelength from Messages where user =?");
BoundStatement boundStatement = new BoundStatement(ps);
ResultSet rs =session.execute ( boundStatement.bind("Andy"));

We can now loop through the result set (here we are assuming only one image comes back)

ByteBuffer bImage=null;
for (Row row : rs) {
 bImage = row.getBytes("image") ;
 length=row.getInt("imagelength");
}

However to display the image we will need it as a byte array.  We can’t use bImage.get() as this reaches down in to the raw buffer (see: https://groups.google.com/a/lists.datastax.com/forum/#!searchin/java-driver-user/blob$20ByteBuffer/java-driver-user/4_KegVX0teo/2OOZ8YOwtBcJ for details )  Instead we can use :

byte image[]= new byte[length];
image=Bytes.getArray(bImage);

In the servlet we can return this image in one of 2 ways:

OutputStream out = response.getOutputStream();
response.setContentType("image/png");
response.setContentLength(image.length);
out.write(Image);

Writes the image as a single lump which may use too much memory.  You might be better using a bufferedinput stream (http://stackoverflow.com/questions/2979758/writing-image-to-servlet-response-with-best-performance

InputStream is = new ByteArrayInputStream(Image);
BufferedInputStream input = new BufferedInputStream(is);
byte[] buffer = new byte[8192];
for (int length = 0; (length = input.read(buffer)) > 0;) {
    out.write(buffer, 0, length);
}
out.close();

9 comments:

  1. Why ByteBuffer instead of ByteArray?

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Wohh I love it, I mean this blog is just awesome. I personally love this informative article… Keep Posting such information… Keep Going!
    UK VPS Hosting

    ReplyDelete
  4. Very Nice Blog, You are spreading very good information among us… Yes Web Hosting plays very important role in business world. And it is important to have the best hosting services.
    UK VPS Hosting

    ReplyDelete
  5. I really appreciate this post and I like this very much. I am waiting for new post here and Please keep it up in future.

    CloudBox99 offers you with the best Cloud server hosting service in Hyderabad and facilitates enterprises to transform digitally. We keep you covered in terms of all your IT requirements with unmatched expertise and deep domain knowledge

    ReplyDelete
  6. Very Great article it was quite beneficial to us.
    Thank you for sharing!
    This site was quite helpful to me also latest technology news 2022 .

    ReplyDelete
  7. This blog has wonderful content, I liked that. you wrote such nice content. Totally Impressive. Keep it up!! I have come up with very important information about Web Hosting if you won't know about it then click on WordPress Web Hosting .

    ReplyDelete
  8. Really a very helpful article thanks for sharing and keep on sharing!

    BSC 1st Year Result 2021 | BSC 2nd Year Result 2021 | BSC 3rd Year Result 2021.

    ReplyDelete