javaimagejdbcimgscalr

Scale Image, then save to DB (Blob)


I have just started using the imgScalr Image Scaling library.

I can get the code to scale the images (I'm pretty sure this works).

BufferedImage fullImage = Scalr.resize((BufferedImage) ImageIO.read(imageStream), fullImageSize);
BufferedImage thumbImage = Scalr.resize(fullImage, thumbImageSize);


Backstory
This is used in a tomcat6 webapp. I pass the image onto a servlet, and read it into an InputStream called "imageStream".

Before resizing/scaling the image, what I was doing was taking that InputStream and saving it to the DB (Oracle11+) Blob field using a PreparedStatement, like so:

PreparedStatement st = con.prepareStatement(SQL);
st.setBlob(1, imageStream);

This was working fine as I could save it no problem and retrieve it with no problems.


The Issue
The issue is now that I'm scaling the image(s) they are being converted to a BufferedImage which I can't save directly to the DB using my PreparedStatement.

Instead, what I'm trying to do is convert the BufferedImage to a ByteArrayOutputStream which then gets read into an InputStream, see code below:

BufferedImage fullImage = Scalr.resize((BufferedImage) ImageIO.read(imageStream), fullImageSize);
BufferedImage thumbImage = Scalr.resize(fullImage, thumbImageSize);

ByteArrayOutputStream fullImageArray = new ByteArrayOutputStream();
ByteArrayOutputStream thumbImageArray = new ByteArrayOutputStream();

ImageIO.write(fullImage, imageMimeType, fullImageArray);
ImageIO.write(thumbImage, imageMimeType, thumbImageArray);

InputStream fullImageStream = new ByteArrayInputStream(fullImageArray.toByteArray());
InputStream thumbImageStream = new ByteArrayInputStream(thumbImageArray.toByteArray());

// DB INITIALISATION STUFF

PreparedStatement st = con.prepareStatement(SQL);
st.setBlob(1, fullImageStream);
st.setBlob(2, thumbImageStream);


Error Details
When I execute the statement, I get a java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into. Which I know that it clearly means that I'm trying to insert a NULL value into the column, so that's not the issue.

The problem is that at some point during my conversions or scaling, the image value gets lost and I end up with a null


The Question
The question comes in two parts:

  1. What am I doing wrong?
  2. Is there are better way to scale an Image in java and save it to a DB (Blob) field?

Solution

  • This issue was caused by the commonly known problem of Pebcak, or in this case "developer error"!

    For future reference, what I did wrong was that I had used the incorrect image type for the ImageIO.read method:

    Problematic:
    ImageIO.write(fullImage, imageMimeType, fullImageArray);

    "imageMimeType" was the full mime type, so in this case it was "image/jpg". This is incorrect as the value should have been simply "jpg" which is what the ImageIO.write() method was expecting.

    Fixed:
    ImageIO.write(fullImage, imageMimeType.replace("image/", ""), fullImageArray);

    I know that the replace is safe in this case as the string will always follow that pattern.