使用 JAI 读取时对图像进行二次采样
我已经读取了相当大的图像(jpeg)的应用程序,但只需要处理较小的图像,因此我使用类似的内容对它们进行子采样
ImageReadParam param = reader.getDefaultReadParam();
param.setSourceSubsampling(4, 4, 0, 0);
img = reader.read(0);
但是,由于jpeg阅读器中的一个错误,它无法处理我已经回退的一些元数据其他方法,一种是使用 JAI 读取图像,然后调整大小(代码如下,不是我必须使用反射,因为某些部署环境没有可用的 JAI,我知道我可以更好地围绕此进行设计,但事实就是如此) 。
try {
Class<?> c = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.JAI");
if (c != null) {
URL url = new URL("file://" + file.getAbsolutePath());
Method m = c.getMethod("create", String.class, Object.class);
Object pi = m.invoke(null, "url", url);
img = (BufferedImage) pi.getClass().getMethod("getAsBufferedImage").invoke(pi);
}
} catch (Throwable tt) {
// ...
}
然而,有些图像非常大,我时不时地会出现内存不足的异常,无论如何,当我以使用 ImageReader 读取图像的方式读取图像时,我是否可以让 JAI 对图像进行二次采样?
An application I have reads in quite large images (jpegs) but only needs to work with smaller images so I subsample them with something like
ImageReadParam param = reader.getDefaultReadParam();
param.setSourceSubsampling(4, 4, 0, 0);
img = reader.read(0);
However, due to a bug in the jpeg reader that does not handle some meta data that I have fall back to other methods, one is using JAI to read the image and then resize (code is below, not I have to use reflection as some deployment environments don't have JAI available, I know I could design around this better but that's how it is).
try {
Class<?> c = ImageUtil.class.getClassLoader().loadClass("javax.media.jai.JAI");
if (c != null) {
URL url = new URL("file://" + file.getAbsolutePath());
Method m = c.getMethod("create", String.class, Object.class);
Object pi = m.invoke(null, "url", url);
img = (BufferedImage) pi.getClass().getMethod("getAsBufferedImage").invoke(pi);
}
} catch (Throwable tt) {
// ...
}
However some of the images are really large an now and again I get out of memory exceptions, is there anyway I can get JAI to subsample the image when it is read in the manner i read the images using an ImageReader?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我假设当您尝试转换为 BufferedImage 时会抛出内存不足异常?
如果是这种情况,那么也许考虑坚持使用 JAI 的创建方法返回的 RenderedOp,而不是使用 ParameterBlock 和进一步的 JAI 创建来生成缩放图像?
恐怕上面的代码完全未经测试作为标准,但应该可以帮助您入门!
一旦你调整了 RenderedOp 的大小,如果需要的话,你应该能够安全地将其转换为 BufferedImage。
I'm assuming the out of memory exception is thrown when you attempt to do the conversion to a BufferedImage?
If that's the case then perhaps considering sticking to the RenderedOp that's returned by JAI's create method and instead use a ParameterBlock and a further JAI create to produce the scaled image?
The above code comes fully untested as standard I'm afraid, but should get you started!
Once you've got that resized RenderedOp you should be able to safely convert it to a BufferedImage if you have to.