【问题标题】:Create a bufferedImage backed by a ByteBuffer创建一个由 ByteBuffer 支持的 bufferedImage
【发布时间】:2020-07-06 19:23:01
【问题描述】:

我想创建一个BufferedImage,它使用预先分配的ByteBuffer 作为其存储或由它“支持”。

我读到有人建议编写自定义 WritableRaster,但我没有看到涉及 ByteBuffers 的适当示例。 这些网页中的大多数现在也已失效。

我该怎么做呢?

【问题讨论】:

    标签: java raster bufferedimage bytebuffer


    【解决方案1】:

    看看我的MappedImageFactoryMappedFileBuffer 课程here。它们是为使用内存映射文件缓冲区而设计的,但由于它们使用相同的接口 (java.nio.Buffer),您应该能够轻松地修改它们以使用预分配的 ByteBuffers。

    这些图像的渲染和显示速度可能不会超快,但可能“足够好”。

    请参阅this answer, using IntBuffers 了解更多想法。这是为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);
        }
    }
    

    输出:

    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
    

    如果您的ByteBuffers 是使用Java 数组(堆)分配的,您也可以使用完全标准的BufferedImages,通过在缓冲区的array() 周围创建一个普通的DataBubfferByte

    【讨论】:

      【解决方案2】:

      偶然发现这个问题试图解决同样的问题。奇怪的是,以下代码似乎比公认的解决方案运行得更快。不知道为什么 - 这看起来很无效......

      final ByteBuffer pImageBuffer = ByteBuffer.allocateDirect((int) size);
      final byte[] buffer = new byte[pImageBuffer.capacity()];
      while (capturing) {
        // populate pImageBuffer via JNI
        pImageBuffer.rewind();
        for (int n = 0; n < pImageBuffer.capacity(); ++n) {
          buffer[n] = pImageBuffer.get(n);
        }
        pImageBuffer.clear();
      
        final BufferedImage retrievedImage = new BufferedImage(captureWidth, captureHeight, BufferedImage.TYPE_4BYTE_ABGR);
        retrievedImage.getRaster().setDataElements(0, 0, captureWidth, captureHeight, buffer);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-12
        • 2016-09-23
        • 1970-01-01
        • 2015-01-27
        • 2013-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多