本文YUV文件以YUV420为例(YUV文件格式可以自行百度)。
方法一;显示在控件上没问题
#define unsigned char U8
bool Yv12ToBgb24(U8
* pYUV
, U8
* pBGR24
, int width
, int height
)
{
if (width
< 1 || height
< 1 || pYUV
== NULL || pBGR24
== NULL)
{
return false;
}
const long len
= width
* height
;
U8
* yData
= pYUV
;
U8
* vData
= &yData
[len
];
U8
* uData
= &vData
[len
>> 2];
int bgr
[3];
int yIdx
, uIdx
, vIdx
, idx
;
for (int i
= 0; i
< height
; i
++)
{
for (int j
= 0; j
< width
; j
++)
{
yIdx
= i
* width
+ j
;
vIdx
= (i
/ 2) * (width
/ 2) + (j
/ 2);
uIdx
= vIdx
;
bgr
[0] = (int)(yData
[yIdx
] + 1.732446 * (uData
[vIdx
] - 128));
bgr
[1] = (int)(yData
[yIdx
] - 0.698001 * (uData
[uIdx
] - 128) - 0.703125 * (vData
[vIdx
] - 128));
bgr
[2] = (int)(yData
[yIdx
] + 1.370705 * (vData
[uIdx
] - 128));
for (int k
= 0; k
< 3; k
++)
{
idx
= (i
* width
+ j
) * 3 + k
;
if (bgr
[k
] >= 0 && bgr
[k
] <= 255)
{
pBGR24
[idx
] = bgr
[k
];
}
else
{
pBGR24
[idx
] = (bgr
[k
] < 0) ? 0 : 255;
}
}
}
}
return true;
}
方法二:保存在本地没问题
bool Yuv420ToRgb(U8
* pYUV
, U8
* pRGB
, int width
, int height
)
{
if (width
< 1 || height
< 1 || pYUV
== NULL || pRGB
== NULL)
{
return false;
}
U8
* pY
= pYUV
;
U8
* pU
= pYUV
+ height
*width
;
U8
* pV
= pU
+ (height
*width
/ 4);
U8
* pBGR
= NULL;
U8 R
= 0;
U8 G
= 0;
U8 B
= 0;
U8 Y
= 0;
U8 U
= 0;
U8 V
= 0;
double temp
= 0;
for (int i
= 0; i
< height
; i
++)
{
for (int j
= 0; j
< width
; j
++)
{
pBGR
= pRGB
+ i
*width
* 3 + j
* 3;
Y
= *(pY
+ i
*width
+ j
);
U
= *pU
;
V
= *pV
;
temp
= Y
+ ((1.773) * (U
- 128));
B
= temp
< 0 ? 0 : (temp
>255 ? 255 : (U8
)temp
);
temp
= (Y
- (0.344) * (U
- 128) - (0.714) * (V
- 128));
G
= temp
< 0 ? 0 : (temp
>255 ? 255 : (U8
)temp
);
temp
= (Y
+ (1.403)*(V
- 128));
R
= temp
< 0 ? 0 : (temp
>255 ? 255 : (U8
)temp
);
*pBGR
= B
;
*(pBGR
+ 1) = G
;
*(pBGR
+ 2) = R
;
if (j
% 2 != 0)
{
*pU
++;
*pV
++;
}
}
if (i
% 2 == 0)
{
pU
= pU
- width
/ 2;
pV
= pV
- width
/ 2;
}
}
return true;
}
保存bmp格式:
typedef struct MyBITMAPFILEHEADER_ST
{
unsigned int bfSize
;
unsigned short bfReserved1
;
unsigned short bfReserved2
;
unsigned int bfOffBits
;
}MyBITMAPFILEHEADER
;
typedef struct MyBITMAPINFOHEADER_ST
{
unsigned int biSize
;
int biWidth
;
int biHeight
;
unsigned short biPlanes
;
unsigned short biBitCount
;
unsigned int biCompression
;
unsigned int biSizeImage
;
int biXPelsPerMeter
;
int biYPelsPerMeter
;
unsigned int biClrUsed
;
unsigned int biClrImportant
;
}MyBITMAPINFOHEADER
;
保存到本地
图片保存的时候,一定要注意bih.biHeight = -height; //图片如果颠倒,去掉负号
void MySaveBmp(U8
*rgbbuf
, int width
, int height
)
{
MyBITMAPFILEHEADER bfh
;
MyBITMAPINFOHEADER bih
;
unsigned short bfType
= 0x4d42;
bfh
.bfReserved1
= 0;
bfh
.bfReserved2
= 0;
bfh
.bfSize
= 2 + sizeof(MyBITMAPFILEHEADER
) + sizeof(MyBITMAPINFOHEADER
) + width
*height
* 3;
bfh
.bfOffBits
= 0x36;
bih
.biSize
= sizeof(MyBITMAPINFOHEADER
);
bih
.biWidth
= width
;
bih
.biHeight
= -height
;
bih
.biPlanes
= 1;
bih
.biBitCount
= 24;
bih
.biCompression
= 0;
bih
.biSizeImage
= 0;
bih
.biXPelsPerMeter
= 5000;
bih
.biYPelsPerMeter
= 5000;
bih
.biClrUsed
= 0;
bih
.biClrImportant
= 0;
FILE
* file
;
fopen_s(&file
, "test11.bmp", "wb");
if (!file
)
{
return;
}
fwrite(&bfType
, sizeof(bfType
), 1, file
);
fwrite(&bfh
, sizeof(bfh
), 1, file
);
fwrite(&bih
, sizeof(bih
), 1, file
);
fwrite(rgbbuf
, width
*height
* 3, 1, file
);
fclose(file
);
}
转载请注明原文地址: https://mac.8miu.com/read-509870.html