【问题标题】:Scale Image, then save to DB (Blob)缩放图像,然后保存到 DB (Blob)
【发布时间】:2014-12-22 23:47:07
【问题描述】:

我刚刚开始使用imgScalr Image Scaling 库。

我可以获得缩放图像的代码(我很确定这可行)。

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


背景故事
这在 tomcat6 webapp 中使用。我将图像传递给一个 servlet,并将其读入一个名为“imageStream”的 InputStream。

在调整图像大小/缩放图像之前,我所做的是获取 InputStream 并使用 PreparedStatement 将其保存到 DB (Oracle11+) Blob 字段,如下所示:

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

这很好,因为我可以毫无问题地保存它并毫无问题地检索它。


问题
现在的问题是我正在缩放它们正在转换为BufferedImage 的图像,我无法使用PreparedStatement 直接将其保存到数据库中。

相反,我正在尝试将BufferedImage 转换为ByteArrayOutputStream,然后将其读入InputStream,请参见下面的代码:

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);


错误详情
当我执行语句时,我得到一个java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into。我知道这显然意味着我正在尝试将 NULL 值插入列中,所以这不是问题。

问题是,在我的转换或缩放过程中,图像值会丢失,我最终得到null


问题
问题分为两部分:
  1. 我做错了什么?
  2. 有没有更好的方法在 java 中缩放图像并将其保存到 DB (Blob) 字段?

【问题讨论】:

  • 尝试在ImageIO.write(thumbImage, imageMim....) 之后调用fullImageArray.close()thumbImageArray.close()。我的猜测:输出流没有被刷新,因此输入流没有数据。您应该检查 fullImageArray.toByteArray().length 是什么,拇指图像也是如此。
  • @ug_ 两者都有'.close()',但没有区别(两个数组的长度都是0,在'close'之前和之后)。
  • 不确定这是否有帮助,但我在 jre7 上。
  • 您是否检查过图像的大小调整是否正确?例如检查宽度和高度是否 > 0。或者可能设置一个使用 Scalr 库从文件中获取图像的小应用程序,重新调整大小并保存。
  • @ug_ 是的,两个图像的大小都正确调整... fullImage:宽度 = 450 高度 = 450,拇指图像:宽度 = 150 高度 = 150。正如您指出的那样,@ 987654339@ 被写入ByteArrayOutputStream。由于某种原因,数据丢失了。

标签: java image jdbc imgscalr


【解决方案1】:

这个问题是由Pebcak这个众所周知的问题引起的,或者在这种情况下是“开发者错误”!

为了将来参考,我做错的是我为 ImageIO.read 方法使用了不正确的图像类型:

有问题:
ImageIO.write(fullImage, imageMimeType, fullImageArray);

"imageMimeType" 是完整的 mime 类型,所以在本例中是 "image/jpg"。这是不正确的,因为该值应该只是“jpg”,这是 ImageIO.write() 方法所期望的。

已修复:
ImageIO.write(fullImage, imageMimeType.replace("image/", ""), fullImageArray);

我知道replace 在这种情况下是安全的,因为字符串将始终遵循该模式。

【讨论】:

  • 很好地解决了这个问题,感谢您回来回答您自己的问题。这可能会帮助该问题的未来读者解决他们自己的问题,这就是网站的内容。确保一旦有答案就接受你的答案(我认为在你这样做之前会有延迟)!
猜你喜欢
  • 1970-01-01
  • 2016-04-21
  • 1970-01-01
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
  • 2011-09-03
  • 2018-06-11
  • 2011-07-19
相关资源
最近更新 更多