对BufferedImage使用IntBuffer [英] Using IntBuffer for BufferedImage

查看:93
本文介绍了对BufferedImage使用IntBuffer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如书名aleady所说,它想要创建一个由特定(已经存在)IntBuffer支持的BufferedImage.

As the title aleady says, it want to create a BufferedImage that is backed by a specific (already existing) IntBuffer.

到目前为止,我有以下代码:

Up to this point, I have the following code:

final IntBuffer buf = ...;
DataBuffer dbuf = new DataBuffer(DataBuffer.TYPE_INT,size) {
    public void setElem(int bank, int i, int val) {
        buf.put(i,val);
    }
    public int getElem(int bank, int i) {
        return buf.get(i);
    }
};
ColorModel cm = ColorModel.getRGBdefault();
SampleModel sm = cm.createCompatibleSampleModel(dim.width,dim.height);
WritableRaster raster = WritableRaster.createWritableRaster(sm,dbuf,null);
BufferedImage img = new BufferedImage(cm,raster,false,new Hashtable<>());

但是此代码显示以下错误:

This code however shows the following error:

Exception in thread "main" java.awt.image.RasterFormatException: IntegerComponentRasters must haveinteger DataBuffers
at sun.awt.image.IntegerComponentRaster.<init>(Unknown Source)
at sun.awt.image.IntegerInterleavedRaster.<init>(Unknown Source)
at sun.awt.image.IntegerInterleavedRaster.<init>(Unknown Source)
at java.awt.image.Raster.createWritableRaster(Unknown Source)
at test.Test.main(Test.java:100)

(该行是创建WritableRaster的那一行.)对我来说非常重要,不必复制数据,因为我将BufferedImage主要用作舒适的接口来写入基础IntBuffer(有一些例外).

(The line is the one where the WritableRaster is created.) It is very important to me that the data doesn´t have to be copied, because I´ll use BufferedImage mainly as a comfortable interface to write to the underlying IntBuffer (with some few exceptions).

推荐答案

我遇到了一个非常相似的问题,试图创建由nio ByteBuffer 支持的 DataBuffer .您尝试做的事情是可能的,但是不能使用 Raster.createWritableRaster 方法(我认为这是一个错误,但是很长一段时间以来都是这样,所以不要指望它会在任何时间被修复很快).您需要直接创建可写栅格的实例.

I had a very similar problem, trying to create a DataBuffer backed by a nio ByteBuffer. What you are trying to do is possible, but not using the Raster.createWritableRaster methods (I think it's a bug, but it's been like that for ages, so don't expect it to be fixed any time soon). You need to directly create an instance of a writable raster.

要么:

WritableRaster = new sun.awt.image.SunWritableRaster(...);

或者,创建您自己的 WritableRaster 子类(这很简单,您实际上不需要重写任何方法,除了 toString 可以帮助调试).

Or, create your own subclass of WritableRaster (it's trivial, you don't actually need to override any methods, except maybe toString to aid debugging).

class GenericWritableRaster extends WritableRaster {
    public GenericWritableRaster(SampleModel model, DataBuffer buffer, Point origin) {
        super(model, buffer, origin);
    }
}

WritableRaster = new GenericWritableRaster(...);

对于一些启发,您可以看一下我的MappedImageFactory 类以了解如何使用它.

For some inspiration, you can have a look at my GenericWritableRaster implementation, and
the MappedImageFactory class for how to use it.

生成的图像将始终为 BufferedImage.TYPE_CUSTOM 类型(因此可能比Java慢),但是如果您已经有一个库将图像保存在库中,那么这对您来说可能没有问题.图形卡的RAM.

The resulting images will always be of type BufferedImage.TYPE_CUSTOM (and thus probably slow from Java), but this is probably no problem for you if you have a library that already holds the images in the graphics card's RAM.

更新,这是基于您的代码的SSCCE PoC:

Update, here's an SSCCE PoC based on your code:

public class BufferTest {
    public static void main(String[] args) {
        Dimension dim = new Dimension(100, 100);
        int size = dim.width * dim.height;

        final IntBuffer buf = IntBuffer.wrap(new int[size]);

        DataBuffer dbuf = new DataBuffer(DataBuffer.TYPE_INT, size) {
            public void setElem(int bank, int i, int val) {
                buf.put(i, val);
            }

            public int getElem(int bank, int i) {
                return buf.get(i);
            }
        };
        ColorModel cm = ColorModel.getRGBdefault();
        SampleModel sm = cm.createCompatibleSampleModel(dim.width, dim.height);
        WritableRaster raster = new WritableRaster(sm, dbuf, new Point()) {};
        BufferedImage img = new BufferedImage(cm, raster, false, null);

        System.err.println("img: " + img);
    }
}

打印:

img: BufferedImage@234441b6: type = 0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000 com.twelvemonkeys.image.BufferTest$2@563625d0

这篇关于对BufferedImage使用IntBuffer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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