Convert raw pixel data (as byte array) to BufferedImage

耗尽温柔 提交于 2019-12-11 23:45:12

问题


I have a requirement to use a native library which reads some proprietary image file formats (something about not reinventing our own wheel). The library works fine, it's just sometimes the images can get pretty big (the record I've seen being 13k x 15k pixels). The problem is my poor JVM keeps dying a painful death and / or throwing OutOfMemoryError's any time the images start getting huge.

Here's what I have running

//the bands, width, and height fields are set in the native code
//And the rawBytes array is also populated in the native code.

public BufferedImage getImage(){
    int type = bands == 1 ? BufferedImage.TYPE_BYTE_GRAY : BufferedImage.TYPE_INT_BRG;
    BufferedImage bi = new BufferedImage(width, height, type);
    ImageFilter filter = new RGBImageFilter(){
        @Override
        public int filterRGB(int x, int y, int rgb){
            int r, g, b;
            if (bands == 3) {
                r = (((int) rawBytes[y * (width / bands) * 3 + x * 3 + 2]) & 0xFF) << 16;
                g = (((int) rawBytes[y * (width / bands) * 3 + x * 3 + 1]) & 0xFF) << 8;
                b = (((int) rawBytes[y * (width / bands) * 3 + x * 3 + 0]) & 0xFF);
            } else {
                b = (((int) rawBytes[y * width + x]) & 0xFF);
                g = b << 8;
                r = b << 16;
            }
            return 0xFF000000 | r | g | b;
        }
    };

    //this is the problematic block
    ImageProducer ip = new FilteredImageSource(bi.getSource(), filter);
    Image i = Toolkit.getDefaultToolkit().createImage(ip);
    Graphics g = bi.createGraphics();
    //with this next line being where the error tends to occur.
    g.drawImage(i, 0, 0, null);
    return bi;
}

This snippet works great for most images so long as they're not obscenely large. Its speed is also just fine. The problem is that that Image drawing onto the BufferedImage step swallows way too much memory.

Is there a way I could skip that step and go directly from raw bytes to buffered image?


回答1:


Use the RawImageInputStream from jai. This does require knowing information about the SampleModel, which you appear to have from the native code.

Another option would be to put your rawBytes into a DataBuffer, then create a WritableRaster, and finally create a BufferedImage. This is essentially what the RawImageInputStream would do.



来源:https://stackoverflow.com/questions/28161834/convert-raw-pixel-data-as-byte-array-to-bufferedimage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!