关于C#:如何将RGB更改为BGR

how to change RGB to BGR

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

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

这是原始的JPEG图像:

original

这是图像从JPEG转换为BMP

jpeg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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);

以下代码显示了我用于彩色图像的调色板。第一个字节表示蓝色部分,第二个字节表示绿色部分,第三个字节表示红色部分(我不确定,我在代码中对此进行了注释)

1
2
3
4
5
6
7
8
9
10
11
12
13
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的转换很简单,只需在一个机器字中交换字节即可。您需要执行以下操作:

1
2
3
4
5
6
7
8
9
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;
}


现在,在编辑过的问题中查看发布图像中的颜色后,我可以看到问题实际上是红色和绿色部分已互换-蓝色部分很好。

最初的描述有些误导,因为您所说的"蓝色"和"绿色"实际上更接近"青色"和"黄色绿色"。单纯的字节交换不能使纯正的"蓝色"变成紫色,因为洋红色是蓝色和红色的混合体。但是,青色是蓝色和绿色的混合,但是当绿色与红色交换时,您的确会获得紫色。

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