I want to create a BufferedImage
that uses a pre-allocated ByteBuffer
as its storage or is "backed" by it.
I've read about people suggesting to write a custom WritableRaster
but I've seen no proper example involving ByteBuffers
.
Most of these web pages are defunct now as well.
How would I go about doing this?
Have a look at my MappedImageFactory
and MappedFileBuffer
classes here. They are made for using memory-mapped file buffers, but as they use the same interface (java.nio.Buffer
), you should easily be able to modify them to use pre-allocated ByteBuffer
s.
These images probably won't be super-fast to render and display, but may be "good enough".
See this answer, using IntBuffer
s for more ideas. Here's that code modified for ByteBuffer
:
public class ByteBufferTest {
public static void main(String[] args) {
Dimension dim = new Dimension(100, 100);
int size = dim.width * dim.height * 4;
final ByteBuffer buf = ByteBuffer.allocate(size);
DataBuffer dbuf = new DataBuffer(DataBuffer.TYPE_BYTE, size) {
@Override
public void setElem(int bank, int i, int val) {
buf.put(i, (byte) val);
}
@Override
public int getElem(int bank, int i) {
return buf.get(i);
}
};
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorModel cm = new ComponentColorModel(cs, new int[]{8, 8, 8, 8}, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
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);
}
}
Output:
img: BufferedImage@4f3f5b24: type = 0 ColorModel: #pixelBits = 32 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@15aeb7ab transparency = 1 has alpha = true isAlphaPre = false ByteBufferTest$2@7b23ec81
If your ByteBuffer
s are allocated using Java arrays (heap), you could probably also use completely standard BufferedImage
s, by creating a normal DataBubfferByte
around the buffer's array()
.