You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对Java ByteBuffer中存储的图像数据进行水平/垂直翻转操作

实现结论

完全可以仅通过操作ByteBuffer实现图像的水平/垂直翻转,不需要引入额外的复杂方案,处理后可直接返回ByteBuffer类型的结果。
当前存储的是RGBA 4通道交织格式图像,每个像素占4字节,按行优先顺序排列,只需要通过坐标映射将原像素写入目标位置即可完成翻转,也可以选择原地交换像素实现无额外内存开销的翻转。

代码实现

水平翻转

水平翻转逻辑为同一行内的像素左右交换,y坐标保持不变:

import java.nio.ByteBuffer;

public ByteBuffer flipHorizontal() {
    // 每个像素占4字节(RGBA顺序)
    int pixelByteLength = 4;
    // 新建和原缓冲区大小一致的缓冲区,若需保持和原缓冲区相同字节序可追加.order(imageBuffer.order())
    ByteBuffer flippedBuffer = ByteBuffer.allocateDirect(imageBuffer.capacity());
    
    for (int y = 0; y < imageHeight; y++) {
        for (int x = 0; x < imageWidth; x++) {
            // 计算原像素首字节偏移
            int srcOffset = (y * imageWidth + x) * pixelByteLength;
            // 水平翻转后的目标x坐标
            int targetX = imageWidth - 1 - x;
            int targetOffset = (y * imageWidth + targetX) * pixelByteLength;
            
            // 复制RGBA四个通道的字节数据
            flippedBuffer.put(targetOffset, imageBuffer.get(srcOffset));
            flippedBuffer.put(targetOffset + 1, imageBuffer.get(srcOffset + 1));
            flippedBuffer.put(targetOffset + 2, imageBuffer.get(srcOffset + 2));
            flippedBuffer.put(targetOffset + 3, imageBuffer.get(srcOffset + 3));
        }
    }
    // 重置缓冲区指针到起始位置,方便后续读取
    flippedBuffer.flip();
    return flippedBuffer;
}

垂直翻转

垂直翻转逻辑为同一列的像素上下交换,x坐标保持不变:

public ByteBuffer flipVertical() {
    int pixelByteLength = 4;
    ByteBuffer flippedBuffer = ByteBuffer.allocateDirect(imageBuffer.capacity());
    
    for (int y = 0; y < imageHeight; y++) {
        // 垂直翻转后的目标y坐标
        int targetY = imageHeight - 1 - y;
        for (int x = 0; x < imageWidth; x++) {
            int srcOffset = (y * imageWidth + x) * pixelByteLength;
            int targetOffset = (targetY * imageWidth + x) * pixelByteLength;
            
            flippedBuffer.put(targetOffset, imageBuffer.get(srcOffset));
            flippedBuffer.put(targetOffset + 1, imageBuffer.get(srcOffset + 1));
            flippedBuffer.put(targetOffset + 2, imageBuffer.get(srcOffset + 2));
            flippedBuffer.put(targetOffset + 3, imageBuffer.get(srcOffset + 3));
        }
    }
    flippedBuffer.flip();
    return flippedBuffer;
}

补充说明

  • 以上示例采用新建缓冲区的方式实现,逻辑简单不易出错,适合绝大多数场景。如果需要原地翻转节省内存,可以遍历一半的坐标,两两交换对应位置的像素即可,避免重复交换。
  • 代码中flippedBuffer.flip()是ByteBuffer自带的读写状态切换方法,作用是将缓冲区position重置为0、limit设置为当前写入位置,是标准的缓冲区操作方法,和图像翻转功能无关。
  • 如果原ByteBuffer是堆内存缓冲区,将新建缓冲区的分配方式改为ByteBuffer.allocate()即可保持类型一致。

内容的提问来源于stack exchange,提问作者Anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:57:02