在使用一些图像处理SDK时,我们常常会遇到一些图像格式的限制,比如我们从相机流中获取了RGB数据,但是在用某些SDK时却发现SDK不能直接支持该类数据,我们可能需要进行进一步的转换才能调用SDK。因此为了方便广大开发者,本文提供了一些常见的图像转换方法。
####先介绍下转换中可能用到的一些函数:其中包括RGB和YUV的互换函数,源于网上流传较多的一些公式,以及经常重复用到的对齐函数
// RGB、YUV互换
int rgbToY(int r, int g, int b) {
return (((66 * r + 129 * g + 25 * b + 128) >> 8) + 16);
}
int rgbToU(int r, int g, int b) {
return (((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128);
}
int rgbToV(int r, int g, int b) {
return (((112 * r - 94 * g - 18 * b + 128) >> 8) + 128);
}
int yuvToR(int y, int u, int v) {
return (int) ((y & 0xFF) + 1.4075 * ((v & 0xFF) - 128));
}
int yuvToG(int y, int u, int v) {
return (int) ((y & 0xFF) - 0.3455 * ((u & 0xFF) - 128) - 0.7169 * ((v & 0xFF) - 128));
}
int yuvToB(int y, int u, int v) {
return (int) ((y & 0xFF) + 1.779 * ((u & 0xFF) - 128));
}
int alignIntToByte(int c) {
return c & 0xFF;
}
1. RGBA32
转换为BGR24
举个例子,对于4x2的图片,RGBA32
格式内容为:
R1 G1 B1 A1 R2 G2 B2 A2 R3 G3 B3 A3 R4 G4 B4 A4
R5 G5 B5 A5 R6 G6 B6 A6 R7 G7 B7 A7 R8 G8 B8 A8
那么若需要转化为BGR24
,内容将变成:
B1 G1 R1 B2 G2 R2 B3 G3 R3 B4 G4 R4
B5 G5 R5 B6 G6 R6 B7 G7 R7 B8 G8 R8
BGR24
内容为3个byte
一组,RGBA32
内容为4个byte
一组。因此,对于第一组RGBA32(R1 G1 B1 A1)
和第一组BGR24(B1 G1 R1)
,其对应关系为:
bgr24[0] = Rgba32[2];
bgr24[1] = Rgba32[1];
bgr24[2] = Rgba32[0];
对应的转换代码:
void rgba32ToBgr24(char *rgba32, char *bgr24, int width, int height) {
int groupNum = width * height;
int bgr24Index = 0;
int rgba32Index = 0;
for (int i = 0; i < groupNum; i++) {
*(bgr24 + bgr24Index) = *(rgba32 + rgba32Index + 2);
*(bgr24 + bgr24Index + 1) = *(rgba32 + rgba32Index + 1);
*(bgr24 + bgr24Index + 2) = *(rgba32 + rgba32Index);
bgr24Index += 3;
rgba32Index += 4;
}
}
2.BGR24
转换为NV21
BGR24
的每一组 B G R
数据对应了一个像素点,而NV21
是一种YUV
数据,YUV
数据的每个