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:
- What am I doing wrong?
- Is there are better way to scale an Image in java and save it to a DB (Blob) field?
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 theImageIO.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.