如何将 BGRA 缓冲区转换为 RGBA 缓冲区格式?

Posted

技术标签:

【中文标题】如何将 BGRA 缓冲区转换为 RGBA 缓冲区格式?【英文标题】:How to Convert BGRA buffer to RGBA buffer format? 【发布时间】:2012-11-16 19:27:20 【问题描述】:

如何在 C++ 中将 BGRA 缓冲区转换为 RGBA 缓冲区格式

void ConvertBetweenBGRAandRGBA(unsigned char* input, int pixel_width,int pixel_hight,
                           unsigned char* output) 

        for (int y = 0; y < pixel_hight; y++) 
        for (int x = 0; x < pixel_width; x++) 
        const unsigned char* pixel_in = &input[y * x * 4];

        unsigned char* pixel_out = &output[y * x * 4];
        pixel_out[0] = pixel_in[2];
        pixel_out[1] = pixel_in[1];
        pixel_out[2] = pixel_in[0];
        pixel_out[3] = pixel_in[3];
     

但我没有得到背景颜色。

有人帮帮我吗?

【问题讨论】:

如果你没有得到背景颜色,那么你到底得到了什么?给出一个例子值和你得到的值。您是否已验证您的 for 循环是否在执行您想要的操作? 【参考方案1】:

这不是 C#,所以请适当地重新标记它。

假设这是位图数据,首先需要弄清楚图像的步幅。步幅是每行像素使用的字节数。这并不总是等于bytes_per_pixel * pixels_per_row。它通常与四个字节对齐,所以在这种情况下(因为 ARGB 像素每个像素使用四个字节)你应该没问题。

其次,您获取像素(x,y)地址的公式是错误的。像素以行优先顺序存储。这意味着,从像素缓冲区中的偏移量 0 开始,您将看到一整行像素数据;然后是另一个完整的行;等等。每行像素数据都有一个完整的字节步长。

可以这样做:

const unsigned char* pixel_in = &input[((y * pixel_width) + x) * 4];

但是如果你的stride确实等于图片宽度,就不需要每次都计算地址,因为像素会按顺序存储:

void ConvertBetweenBGRAandRGBA(unsigned char* input, int pixel_width,
    int pixel_height, unsigned char* output)

    int offset = 0;

    for (int y = 0; y < pixel_height; y++) 
        for (int x = 0; x < pixel_width; x++) 
            output[offset] = input[offset + 2];
            output[offset + 1] = input[offset + 1];
            output[offset + 2] = input[offset];
            output[offset + 3] = input[offset + 3];

            offset += 4;
        
    

如果仍然无法正确显示,请确认正确的像素封装是什么。它应该是 ARGB 或 BGRA;我从未听说过像素打包为 RGBA。

【讨论】:

【参考方案2】:

Jeff 的 awnser 可以工作,但有一点细节你永远不会存储第一个偏移量。 只需添加一个临时值,它就会像对我一样具有魅力:D

void ConvertBetweenBGRAandRGBA(unsigned char* input, int pixel_width, int pixel_height, unsigned char* output)

    int offset = 0;

    for (int y = 0; y < pixel_height; y++) 
        for (int x = 0; x < pixel_width; x++) 

            auto temp = output[offset];
            output[offset] = input[offset + 2];
            output[offset + 1] = input[offset + 1];
            output[offset + 2] = temp;
            output[offset + 3] = input[offset + 3];

            offset += 4;
        
    

【讨论】:

以上是关于如何将 BGRA 缓冲区转换为 RGBA 缓冲区格式?的主要内容,如果未能解决你的问题,请参考以下文章

从 ARGB 转换为 RGBA

使用 libpng 将位图缓冲区快速编码为 png

Opengl渲染到纹理,但纹理为空

BGRA 的 Tiff 或 Exif 标签

将 RGBA32F 纹理与帧缓冲区一起使用会引发 INVALID_ENUM 错误

iOS录制时如何将PCM缓冲区实时转换为AAC数据?