如何将RGB更改为BGR

how to change RGB to BGR

我正在使用 libjpeg 解码 jpeg 文件并将其写入位图文件。 当我将解压缩的原始图像写入文件时,颜色似乎不正确。例如,蓝色变成紫色,绿色变成橙色。

这是我的示例 jpeg 的 link: https://drive.google.com/file/d/0B3ob0t07z5xEV3hCb0FPQm1ETk0/view?usp=sharing

这是原始 JPEG 图片:

这是从 JPEG 转换为 BMP 的图像

在 Google 上搜索解决方案时,我偶然发现了一些将图像从 RGB 转换为 BGR 的建议。我不是图像方面的专家,但这是解决我的问题的正确方法吗?

如果支持,libjpeg 是否支持 RGB 到 BGR 的转换?下面是我的代码片段:

struct jpeg_decompress_struct cinfo;
unsigned int bytesPerRow = cinfo.output_width * cinfo.num_components;
unsigned char *raw_image;
JSAMPROW row_pointer[1];
int iCount = 0;
unsigned int totalBytes = cinfo.output_width * cinfo.output_height
            * cinfo.num_components;
unsigned long location = totalBytes;
FILE *bmpFile;

while (cinfo.output_scanline < cinfo.image_height) {
    jpeg_read_scanlines(&cinfo, row_pointer, 1);

    for (iCount = bytesPerRow - 1; iCount <= cinfo.image_width * cinfo.num_components; iCount--) {
        raw_image[location--] = row_pointer[0][iCount];
    }
}

/* need to convert RGB to BGR here before writing to file */

fwrite(raw_image, 1, totalBytes, bmpFile);

下面的代码显示了我的彩色图像调色板。第一个字节代表蓝色部分,第二个字节代表绿色部分,第三个字节代表红色部分。(我不确定这个,我在我的代码中评论了这个)

unsigned long long_val;
unsigned char padding;

padding = 0;

long_val = 2;
fwrite(&long_val, 1, 1, bmpFile);
long_val = 1;
fwrite(&long_val, 1, 1, bmpFile);
long_val = 0;
fwrite(&long_val, 1, 1, bmpFile);

fwrite(&padding, 1, 1, bmpFile);

RGB 到 BGR 的转换是在机器字内交换字节的简单问题。你需要做这样的事情:

int i;
char temp;
for( i = 0;  i < raw_image_size;  i += 3 )
{
    //swap R and B; raw_image[i + 1] is G, so it stays where it is.
    temp = raw_image[i + 0];
    raw_image[i + 0] = raw_image[i + 2];
    raw_image[i + 2] = temp;
}

现在查看您在已编辑问题中发布的图像中的颜色,我可以看出问题实际上是红色和绿色分量调换了 - 蓝色分量没问题。

原来的描述有点误导,因为你描述的 "blue" 和 "green" 实际上更接近 "cyan" 和 "yellow green"。纯 "blue" 不能简单地通过字节交换变成紫色,因为洋红色是蓝色和红色的混合。然而青色是蓝色和绿色的混合,但是当绿色与红色交换时,你确实得到了紫色。

我相信可以通过在 BMP 文件的 DIB header "bitmask" 字段中输入正确的值来更正此问题(参见 https://en.wikipedia.org/wiki/BMP_file_format)。这些字段指示文件中数据的字节顺序。