如何将RGB更改为BGR

时间:2015-12-02 02:31:02

标签: c bitmap jpeg rgb libjpeg

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

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

这是原始的JPEG图像:

original JPEG image

这是从JPEG转换为BMP的图像

jpeg to bitmap image

在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);

下面的代码显示了我的COLORED图像托盘。第一个字节代表蓝色部分,第二个字节代表绿色部分,第三个字节代表redpart。(我不确定这一点,我在我的代码中对此进行了评论)

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);

2 个答案:

答案 0 :(得分:3)

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;
}

答案 1 :(得分:1)

现在看看已编辑问题中已发布图像中的颜色,我可以看到问题实际上是红色和绿色组件被交换 - 蓝色组件很好。

原始描述有点误导,因为你所描述的“蓝色”和“绿色”实际上更接近“青色”和“黄绿色”。纯粹的“蓝色”不能简单地通过字节交换变成紫色,因为洋红色是蓝色和红色的混合。然而青色是蓝色和绿色的混合,但当绿色与红色交换时,你确实会得到紫色。

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