代码之家  ›  专栏  ›  技术社区  ›  vickirk

使用JAI读取时的次采样图像

  •  0
  • vickirk  · 技术社区  · 15 年前

    我读过一个相当大的图片(jpeg)的应用程序,但只需要处理较小的图片,所以我用类似的东西对它们进行子抽样

    ImageReadParam param = reader.getDefaultReadParam();
    param.setSourceSubsampling(4, 4, 0, 0);
    img = reader.read(0);
    

    但是,由于jpeg阅读器中的一个bug无法处理某些元数据,我不得不返回到其他方法,其中一个bug是使用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子样本的图像,当它是读的方式,我读的图像使用一个图像阅读器?

    2 回复  |  直到 12 年前
        1
  •  0
  •   Jasoon    15 年前

    我假设在尝试转换为BufferedImage时抛出内存不足异常?

    如果是这样的话,那么可能考虑使用jai的create方法返回的renderup,而是使用参数块和进一步的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);
    

    恐怕上面的代码完全没有经过标准测试,但是应该可以让你开始!

    一旦你得到了大小调整的renderup,你应该能够安全地将它转换为bufferedimage,如果你必须这样做的话。

        2
  •  2
  •   Jordan    12 年前
    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();