将原始像素数据(作为字节数组)转换为BufferedImage [英] Convert raw pixel data (as byte array) to BufferedImage

查看:508
本文介绍了将原始像素数据(作为字节数组)转换为BufferedImage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用一个本机库,该库读取某些专有的图像文件格式(关于不重新发明自己的车轮的某种做法).该库运行良好,只是有时图像会变得很大(我见过的记录是13k x 15k像素).问题是我的可怜的JVM总是死得很痛苦,并且/或者在图像开始变大时就抛出OutOfMemoryError.

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.

这就是我正在跑步的

//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;
}

此代码段适用于大多数图像,只要它们不会显得过大即可.它的速度也还不错.问题在于,在BufferedImage步骤上绘制Image会占用太多内存.

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?

推荐答案

使用

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

另一种选择是将您的rawBytes放入

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.

这篇关于将原始像素数据(作为字节数组)转换为BufferedImage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆