YUV文件转RGB并保存为bmp格式

mac2025-12-31  8

本文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)); // b分量 bgr[1] = (int)(yData[yIdx] - 0.698001 * (uData[uIdx] - 128) - 0.703125 * (vData[vIdx] - 128)); // g分量 bgr[2] = (int)(yData[yIdx] + 1.370705 * (vData[uIdx] - 128)); // r分量 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; } //找到Y、U、V在内存中的首地址 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++) { //找到相应的RGB首地址 pBGR = pRGB + i*width * 3 + j * 3; //取Y、U、V的数据值 Y = *(pY + i*width + j); U = *pU; V = *pV; //yuv转rgb公式 //yuv转rgb公式 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); //将转化后的rgb保存在rgb内存中,注意放入的顺序b是最低位 *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) { //printf("Could not write file\n"); 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); }
最新回复(0)