使用jai读取时的子采样图像

vm0i2vca  于 2021-07-05  发布在  Java
关注(0)|答案(2)|浏览(333)

我有一个应用程序可以读取相当大的图像(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) {
// ...
}

然而,有些图像确实很大,有时我会出现内存不足的异常,我是否可以让jai在以我使用图像阅读器读取图像的方式读取图像时对图像进行子采样?

3df52oht

3df52oht1#

我假设在您尝试转换为BuffereImage时抛出内存不足异常?
如果是这样的话,那么是否考虑使用jai的create方法返回的renderop,而使用parameterblock和jai的create来生成缩放图像?

ParameterBlock paramBlock = new ParameterBlock();
paramBlock.addSource(((RenderedOp) pi).createInstance()); // Updated this
paramBlock.add(0.5f); // x Scale (Change these two Scale values!)
paramBlock.add(0.5f); // y Scale
paramBlock.add(0.0f); // x Translate
paramBlock.add(0.0f); // y Translate
paramBlock.add(new InterpolationBilinear()); // I think this Interpolation should work...)
RenderedOp resized = JAI.create("scale", paramBlock, null);

上面的代码是完全未经测试的标准,我恐怕,但应该让你开始!
一旦你有了调整大小的renderop,你应该能够安全地把它转换成bufferedimage,如果你必须的话。

6yjfywim

6yjfywim2#

RenderedOp rop = JAI.create("fileload", file.getAbsolutePath());

ParameterBlock pb = new ParameterBlock();
pb.addSource(rop);
pb.add(0.5f);
pb.add(0.5f);
rop = JAI.create("scale", pb);

// For better looking results, but slower:
// rop = JAI.create("SubsampleAverage", pb);

BufferedImage bufImg = rop.getAsBufferedImage();

相关问题