YUY2转RGB的代码BYTE* pSrc; DWORD* pDest; DWORD R, G, B;for(y = 0; y < Height; y++) { for(x = 0; x < Width; x += 2) { int Y0 = *pSrc++; int U = *pSrc++; int Y1 = *pSrc++; int V = *pSrc++;R = 1.164383 * (Y0 - 16) + 1.596027 * (V - 128); G = 1.164383 * (Y0 - 16) - 0.812968 * (V - 128) - 0.391762 * (U - 128); B = 1.164383 * (Y0 - 16) + 2.017232 * (U - 128); if(R < 0) R = 0; if(R > 255) R = 255; if(G < 0) R = 0; if(G > 255) R = 255; if(B < 0) R = 0; if(B > 255) R = 255;*pDest++ = (R << 16) | (G << 8) | b;R = 1.164383 * (Y1 - 16) + 1.596027 * (V - 128); G = 1.164383 * (Y1 - 16) - 0.812968 * (V - 128) - 0.391762 * (U - 128); B = 1.164383 * (Y1 - 16) + 2.017232 * (U - 128);if(R < 0) R = 0; if(R > 255) R = 255; if(G < 0) R = 0; if(G > 255) R = 255; if(B < 0) R = 0; if(B > 255) R = 255;*pDest++ = (R << 16) | (G << 8) | b; } }
to Analyst: 用了你的代码之后白色背景出现黄红色块,不知道是什么缘故? 请指教。
Analyst()把R与B搞错了吧.应该把它们倒一下.
#include <stdio.h> #include <stdlib.h> #include <string.h> /* This C program may be compiled with either a 16-bit C compiler or a 32-bit C compiler. When a 32-bit C compiler is used, compiler flag must be set to pack structure on 2 byte boundary (/Zp2 for Microsoft C compiler) */typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD;/* Reference in is0b059.c. */ #pragma pack(2) typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER; //BMP文件头typedef struct tagBITMAPINFOHEADER{ DWORD biSize; DWORD biWidth; DWORD biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; DWORD biXPelsPerMeter; DWORD biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; //BMP信息头 #pragma pack()short int bmp_wd = 720, bmp_ht = 480; unsigned char bufy [2048], bufu [2048], bufv [2048]; unsigned char bufr [2048], bufg [2048], bufb [2048]; void save_bmp (char *inbase, char *outname, int is411) { /***************************************************************************** * *****************************************************************************/ char filename [81]; short int scanLineSize, r, c,R, G, B, y, u, v; FILE *ou, *Y, *U, *V; BITMAPFILEHEADER fileHd; BITMAPINFOHEADER infoHd;
ou = fopen (outname, "rb"); if (ou != NULL) { fclose (ou); /*printf ("'%s' exist, overwrite ? <Enter> for yes", outname); if (getch () != 13) { if (kbhit ()) getch (); return; } if (kbhit ()) getch (); puts ("");*/ } ou = fopen (outname, "wb"); if (ou == NULL) { printf ("unable to open %s\n", outname); return; } sprintf (filename, "%s.y", inbase); Y = fopen (filename, "rb"); if (Y == NULL) { printf ("Unable to open %s\n", filename); return; } sprintf (filename, "%s.u", inbase); U = fopen (filename, "rb"); if (U == NULL) { printf ("Unable to open %s\n", filename); return; } sprintf (filename, "%s.v", inbase); V = fopen (filename, "rb"); if (V == NULL) { printf ("Unable to open %s\n", filename); return; } scanLineSize = ((bmp_wd + 3)) & ~3; //设置文件头结构 fileHd.bfType = 0x4d42; //bmp标志 fileHd.bfSize = sizeof (fileHd) + sizeof (infoHd) + (long int) scanLineSize * bmp_ht; //整个BMP文件字节数 fileHd.bfReserved1 = 0; fileHd.bfReserved2 = 0; fileHd.bfOffBits = sizeof (fileHd) + sizeof (infoHd); //偏移字节数 //设置信息头格式 infoHd.biSize = sizeof (infoHd); //信息大小 infoHd.biWidth = bmp_wd; //宽 infoHd.biHeight = bmp_ht; //高 infoHd.biPlanes = 1; infoHd.biBitCount = 24; //24位 infoHd.biCompression = 0; infoHd.biSizeImage = (long int) scanLineSize * (long) bmp_ht * 3; infoHd.biXPelsPerMeter = 0; infoHd.biYPelsPerMeter = 0; infoHd.biClrUsed = 0; infoHd.biClrImportant = 0; fwrite (&fileHd, sizeof (fileHd), 1, ou); //写文件头 fwrite (&infoHd, sizeof (infoHd), 1, ou); //写信息头 for (r = 0; r < bmp_ht; r++) { fread (bufy, 1, bmp_wd, Y); if ((is411 == 0) || ((r & 1) == 0)) { fread (bufu, 1, bmp_wd / 2, U); fread (bufv, 1, bmp_wd / 2, V); } fseek (ou, fileHd.bfOffBits + (long int) scanLineSize * (bmp_ht - r - 1) * 3, SEEK_SET); for (c = 0; c < bmp_wd; c++) { y = bufy [c]; u = bufu [c >> 1] - 128; v = bufv [c >> 1] - 128; R = y + 1.375 * v; G = y - 0.34375 * u - 0.703125 * v; B = y + 1.734375 * u; R = max (0, min (255, R)); //R,G,B应该在0~255之间 G = max (0, min (255, G)); B = max (0, min (255, B)); fputc (B, ou); // b fputc (G, ou); // g fputc (R, ou); // r } for (; c < scanLineSize; c++) { fputc (0, ou); //每行空余的部分,每空一个补3个0 fputc (0, ou); fputc (0, ou); }#if 0 if (++r < bmp_ht) { fread (bufy, 1, bmp_wd, Y); fseek (ou, fileHd.bfOffBits + (long int) scanLineSize * (bmp_ht - r - 1) * 3, SEEK_SET); for (c = 0; c < bmp_wd; c++) { y = bufy [c]; u = bufu [c >> 1] - 128; v = bufv [c >> 1] - 128; R = y + 1.375 * v; G = y - 0.34375 * u - 0.703125 * v; B = y + 1.734375 * u; R = max (0, min (255, R)); G = max (0, min (255, G)); B = max (0, min (255, B)); fputc (B, ou); fputc (G, ou); fputc (R, ou); } for (; c < scanLineSize; c++) { fputc (0, ou); fputc (0, ou); fputc (0, ou); } } #endif } printf ("\n"); fclose (ou);
DWORD* pDest;
DWORD R, G, B;for(y = 0; y < Height; y++)
{
for(x = 0; x < Width; x += 2)
{
int Y0 = *pSrc++;
int U = *pSrc++;
int Y1 = *pSrc++;
int V = *pSrc++;R = 1.164383 * (Y0 - 16) + 1.596027 * (V - 128);
G = 1.164383 * (Y0 - 16) - 0.812968 * (V - 128) - 0.391762 * (U - 128);
B = 1.164383 * (Y0 - 16) + 2.017232 * (U - 128);
if(R < 0) R = 0;
if(R > 255) R = 255;
if(G < 0) R = 0;
if(G > 255) R = 255;
if(B < 0) R = 0;
if(B > 255) R = 255;*pDest++ = (R << 16) | (G << 8) | b;R = 1.164383 * (Y1 - 16) + 1.596027 * (V - 128);
G = 1.164383 * (Y1 - 16) - 0.812968 * (V - 128) - 0.391762 * (U - 128);
B = 1.164383 * (Y1 - 16) + 2.017232 * (U - 128);if(R < 0) R = 0;
if(R > 255) R = 255;
if(G < 0) R = 0;
if(G > 255) R = 255;
if(B < 0) R = 0;
if(B > 255) R = 255;*pDest++ = (R << 16) | (G << 8) | b;
}
}
用了你的代码之后白色背景出现黄红色块,不知道是什么缘故?
请指教。
#include <stdlib.h>
#include <string.h>
/* This C program may be compiled with either a 16-bit C compiler or
a 32-bit C compiler. When a 32-bit C compiler is used, compiler
flag must be set to pack structure on 2 byte boundary (/Zp2 for
Microsoft C compiler) */typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;/* Reference in is0b059.c. */
#pragma pack(2)
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER; //BMP文件头typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
DWORD biWidth;
DWORD biHeight;
WORD biPlanes;
WORD biBitCount; DWORD biCompression;
DWORD biSizeImage;
DWORD biXPelsPerMeter;
DWORD biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER; //BMP信息头
#pragma pack()short int bmp_wd = 720, bmp_ht = 480;
unsigned char bufy [2048], bufu [2048], bufv [2048];
unsigned char bufr [2048], bufg [2048], bufb [2048];
void save_bmp (char *inbase, char *outname, int is411) {
/*****************************************************************************
*
*****************************************************************************/
char filename [81];
short int scanLineSize, r, c,R, G, B, y, u, v;
FILE *ou, *Y, *U, *V;
BITMAPFILEHEADER fileHd;
BITMAPINFOHEADER infoHd;
ou = fopen (outname, "rb");
if (ou != NULL) {
fclose (ou);
/*printf ("'%s' exist, overwrite ? <Enter> for yes", outname);
if (getch () != 13) {
if (kbhit ()) getch ();
return;
}
if (kbhit ()) getch ();
puts ("");*/
} ou = fopen (outname, "wb");
if (ou == NULL) {
printf ("unable to open %s\n", outname);
return;
} sprintf (filename, "%s.y", inbase);
Y = fopen (filename, "rb");
if (Y == NULL) {
printf ("Unable to open %s\n", filename);
return;
}
sprintf (filename, "%s.u", inbase);
U = fopen (filename, "rb");
if (U == NULL) {
printf ("Unable to open %s\n", filename);
return;
}
sprintf (filename, "%s.v", inbase);
V = fopen (filename, "rb");
if (V == NULL) {
printf ("Unable to open %s\n", filename);
return;
}
scanLineSize = ((bmp_wd + 3)) & ~3;
//设置文件头结构
fileHd.bfType = 0x4d42; //bmp标志
fileHd.bfSize = sizeof (fileHd) + sizeof (infoHd) +
(long int) scanLineSize * bmp_ht; //整个BMP文件字节数
fileHd.bfReserved1 = 0;
fileHd.bfReserved2 = 0;
fileHd.bfOffBits = sizeof (fileHd) + sizeof (infoHd); //偏移字节数 //设置信息头格式
infoHd.biSize = sizeof (infoHd); //信息大小
infoHd.biWidth = bmp_wd; //宽
infoHd.biHeight = bmp_ht; //高
infoHd.biPlanes = 1;
infoHd.biBitCount = 24; //24位
infoHd.biCompression = 0;
infoHd.biSizeImage = (long int) scanLineSize * (long) bmp_ht * 3;
infoHd.biXPelsPerMeter = 0;
infoHd.biYPelsPerMeter = 0;
infoHd.biClrUsed = 0;
infoHd.biClrImportant = 0;
fwrite (&fileHd, sizeof (fileHd), 1, ou); //写文件头
fwrite (&infoHd, sizeof (infoHd), 1, ou); //写信息头 for (r = 0; r < bmp_ht; r++) {
fread (bufy, 1, bmp_wd, Y);
if ((is411 == 0) || ((r & 1) == 0)) {
fread (bufu, 1, bmp_wd / 2, U);
fread (bufv, 1, bmp_wd / 2, V);
} fseek (ou, fileHd.bfOffBits + (long int) scanLineSize * (bmp_ht - r - 1) * 3, SEEK_SET); for (c = 0; c < bmp_wd; c++) {
y = bufy [c];
u = bufu [c >> 1] - 128;
v = bufv [c >> 1] - 128; R = y + 1.375 * v;
G = y - 0.34375 * u - 0.703125 * v;
B = y + 1.734375 * u; R = max (0, min (255, R)); //R,G,B应该在0~255之间
G = max (0, min (255, G));
B = max (0, min (255, B));
fputc (B, ou); // b
fputc (G, ou); // g
fputc (R, ou); // r
} for (; c < scanLineSize; c++) {
fputc (0, ou); //每行空余的部分,每空一个补3个0
fputc (0, ou);
fputc (0, ou);
}#if 0
if (++r < bmp_ht) {
fread (bufy, 1, bmp_wd, Y); fseek (ou, fileHd.bfOffBits + (long int) scanLineSize * (bmp_ht - r - 1) * 3, SEEK_SET); for (c = 0; c < bmp_wd; c++) {
y = bufy [c];
u = bufu [c >> 1] - 128;
v = bufv [c >> 1] - 128;
R = y + 1.375 * v;
G = y - 0.34375 * u - 0.703125 * v;
B = y + 1.734375 * u;
R = max (0, min (255, R));
G = max (0, min (255, G));
B = max (0, min (255, B));
fputc (B, ou);
fputc (G, ou);
fputc (R, ou);
}
for (; c < scanLineSize; c++) {
fputc (0, ou);
fputc (0, ou);
fputc (0, ou);
}
}
#endif
}
printf ("\n");
fclose (ou);
fclose (Y);
fclose (U);
fclose (V);
} /* save_bmp */main (int noarg, char *argv []) {
if (noarg < 5) {
printf ("Usage: %s <input filename base> <output filename> <width> <height> [411]\n",
argv [0]);
puts ("YUV files format is 4:2:2 unless 411 flag is given");
return (1);
} sscanf (argv [3], "%d", &bmp_wd);
sscanf (argv [4], "%d", &bmp_ht);
save_bmp (argv [1], argv [2], noarg > 5);
return (0);
}
DWORD* pDest;
DWORD R, G, B;for(y = 0; y < Height; y++)
{
for(x = 0; x < Width; x += 2)
{
int Y0 = *pSrc++;
int U = *pSrc++;
int Y1 = *pSrc++;
int V = *pSrc++;R = 1.164383 * (Y0 - 16) + 1.596027 * (V - 128);
G = 1.164383 * (Y0 - 16) - 0.812968 * (V - 128) - 0.391762 * (U - 128);
B = 1.164383 * (Y0 - 16) + 2.017232 * (U - 128);if(R < 0) R = 0;
if(R > 255) R = 255;
if(G < 0) G = 0;
if(G > 255) G = 255;
if(B < 0) B = 0;
if(B > 255) B = 255;*pDest = (R << 16) | (G << 8) | B;
pDest = (DWORD)((BYTE*)pDest + 3);R = 1.164383 * (Y1 - 16) + 1.596027 * (V - 128);
G = 1.164383 * (Y1 - 16) - 0.812968 * (V - 128) - 0.391762 * (U - 128);
B = 1.164383 * (Y1 - 16) + 2.017232 * (U - 128);if(R < 0) R = 0;
if(R > 255) R = 255;
if(G < 0) G = 0;
if(G > 255) G = 255;
if(B < 0) B = 0;
if(B > 255) B = 255;*pDest = (R << 16) | (G << 8) | B;
pDest = (DWORD)((BYTE*)pDest + 3);
}
}
((WORD)((BYTE)(g)) << 8)) | \
(((DWORD)(BYTE)(b)) << 16)))
RGB的格式.楼上的搞错了吧.
bool CClrTransformFilter::ConvertYv12ToRgb24(unsigned char * pYv12Buffer,unsigned char * pRgb24Buffer)
{
if(pYv12Buffer == NULL || pRgb24Buffer == NULL) return false;
long lFrameSize = m_lImageWidth * m_lImageLength;
int i,j;
float Y,U,V;
// transform yv12 data to rgb data
for(i = 0 ; i < m_lImageLength; i++)
{
for(j = 0; j < m_lImageWidth; j++)
{
Y = (float)pYv12Buffer[i * m_lImageWidth + j];
U = (float)pYv12Buffer[lFrameSize + (i/2)* m_lImageWidth /2+ j/2];
V = (float)pYv12Buffer[5* lFrameSize/4 + (i/2) * m_lImageWidth/2 + j/2];
// R Value
pRgb24Buffer[3 * (m_lImageLength - 1 - i) * m_lImageWidth + 3 * j] = (unsigned char)(Y + 1.4019 * (V - 128));
// G Value
pRgb24Buffer[3 * (m_lImageLength - 1 - i) * m_lImageWidth + 3 * j + 1] = (unsigned char)(Y - 0.34414 * (U - 128) - 0.74414 * (V - 128));
// B Value
pRgb24Buffer[3 * (m_lImageLength - 1 - i) * m_lImageWidth + 3 * j + 2] = (unsigned char)(Y + 1.775 * (U - 128));
}
}
return true;
}
www.fourcc.org