RGB to YUV420 原代码: RGB2YUV.CPP文件
RGB to YUV420 原代码: RGB2YUV.CPP文件
#include <stdio.h>
#include <stdlib.h>
#include
<string.h>
#include<iostream>
//转换矩阵
#define MY(a,b,c) (( a* 0.2989 + b* 0.5866
+ c* 0.1145))
#define MU(a,b,c) (( a*(-0.1688) + b*(-0.3312) + c*
0.5000 + 128))
#define MV(a,b,c) (( a* 0.5000 + b*(-0.4184) +
c*(-0.0816) + 128))
//大小判断
#define DY(a,b,c) (MY(a,b,c) > 255 ? 255 :
(MY(a,b,c) < 0 ? 0 : MY(a,b,c)))
#define DU(a,b,c) (MU(a,b,c) > 255 ?
255 : (MU(a,b,c) < 0 ? 0 : MU(a,b,c)))
#define DV(a,b,c) (MV(a,b,c) >
255 ? 255 : (MV(a,b,c) < 0 ? 0 : MV(a,b,c)))
//只处理352*288文件
#define
WIDTH 352
#define HEIGHT 288
//读BMP
void ReadBmp(unsigned char *RGB,FILE *fp);
//转换函数
void Convert(unsigned char *RGB, unsigned char *YUV);
//入口
int main()
{
int i=1;
char file[255];
FILE *fp;
FILE
*fp2;
unsigned char *YUV = NULL;
unsigned char *RGB = NULL;
unsigned int imgSize =
WIDTH*HEIGHT;
if((fp2 = fopen("test.cif", "wb")) ==
NULL)//生成文件名
{
return 0;
}
RGB = (unsigned
char*)malloc(imgSize*6);
YUV = (unsigned
char*)malloc(imgSize +
(imgSize>>1));
for(i=1;
i<2; i++)
{
sprintf(file, "test.bmp",
i);//读取文件
if((fp = fopen(file,
"rb")) == NULL)
continue;
printf("打开文件%s\n",
file);
ReadBmp(RGB,
fp);
Convert(RGB,
YUV);
fwrite(YUV, 1,
imgSize+(imgSize>>1),
fp2);//写入文件
fclose(fp);
}
fclose(fp2);
if(RGB)
free(RGB);
if(YUV)
free(YUV);
printf("完成\n");
system("pause");
return 1;
}
//读BMP
void ReadBmp(unsigned char *RGB,FILE
*fp)
{
int i,j;
unsigned char
temp;
fseek(fp,54, SEEK_SET);
fread(RGB+WIDTH*HEIGHT*3, 1, WIDTH*HEIGHT*3,
fp);//读取
for(i=HEIGHT-1,j=0; i>=0;
i--,j++)//调整顺序
{
memcpy(RGB+j*WIDTH*3,RGB+WIDTH*HEIGHT*3+i*WIDTH*3,WIDTH*3);
}
//顺序调整
for(i=0; (unsigned int)i < WIDTH*HEIGHT*3; i+=3)
{
temp =
RGB[i];
RGB[i] =
RGB[i+2];
RGB[i+2] =
temp;
}
}
void Convert(unsigned char *RGB, unsigned char
*YUV)
{
//变量声明
unsigned int
i,x,y,j;
unsigned char *Y = NULL;
unsigned char *U = NULL;
unsigned char *V =
NULL;
Y =
YUV;
U = YUV + WIDTH*HEIGHT;
V = U +
((WIDTH*HEIGHT)>>2);
for(y=0; y < HEIGHT;
y++)
for(x=0; x < WIDTH;
x++)
{
j =
y*WIDTH +
x;
i =
j*3;
Y[j]
= (unsigned char)(DY(RGB[i], RGB[i+1], RGB[i+2]));
if(x%2 ==
1 && y%2 ==
1)
{
j = (WIDTH>>1) * (y>>1) +
(x>>1);
//上面i仍有效
U[j] = (unsigned
char)
((DU(RGB[i ], RGB[i+1], RGB[i+2])
+
DU(RGB[i-3], RGB[i-2], RGB[i-1])
+
DU(RGB[i -WIDTH*3], RGB[i+1-WIDTH*3], RGB[i+2-WIDTH*3])
+
DU(RGB[i-3-WIDTH*3], RGB[i-2-WIDTH*3], RGB[i-1-WIDTH*3]))/4);
V[j] = (unsigned
char)
((DV(RGB[i ], RGB[i+1], RGB[i+2])
+
DV(RGB[i-3], RGB[i-2], RGB[i-1])
+
DV(RGB[i -WIDTH*3], RGB[i+1-WIDTH*3], RGB[i+2-WIDTH*3])
+
DV(RGB[i-3-WIDTH*3], RGB[i-2-WIDTH*3],
RGB[i-1-WIDTH*3]))/4);
}
}
}
YUV420 to RGB 原代码: yuv2rgb.cpp文件
#include <stdio.h>
#include <stdlib.h>
#include
<iostream>
#define WIDTH 352
#define HEIGHT 288
//转换矩阵
double
YuvToRgb[3][3] = {1, 0,
1.4022,
1, -0.3456,
-0.7145,
1, 1.771, 0};
//根据RGB三分量写BMP,不必关注
int WriteBmp(int width, int height, unsigned char
*R,unsigned char *G,unsigned char *B, char *BmpFileName);
//转换函数
int Convert(char *file, int width, int height, int
n)
{
//变量声明
int i =
0;
int temp = 0;
int x =
0;
int y = 0;
int fReadSize =
0;
int ImgSize = width*height;
FILE
*fp = NULL;
unsigned char* yuv =
NULL;
unsigned char* rgb = NULL;
unsigned char* cTemp[6];
char BmpFileName[256];
//申请空间
int FrameSize = ImgSize +
(ImgSize >> 1);
yuv = (unsigned char
*)malloc(FrameSize);
rgb = (unsigned char
*)malloc(ImgSize*3);
//读取指定文件中的指定帧
if((fp = fopen(file, "rb")) ==
NULL)
return
0;
fseek(fp, FrameSize*(n-1),
SEEK_CUR);
fReadSize = fread(yuv, 1, FrameSize,
fp);
fclose(fp);
if(fReadSize <
FrameSize)
return
0;
//转换指定帧 如果你不是处理文件 主要看这里
cTemp[0] =
yuv;
//y分量地址
cTemp[1] = yuv +
ImgSize;
//u分量地址
cTemp[2] = cTemp[1] +
(ImgSize>>2); //v分量地址
cTemp[3] =
rgb;
//r分量地址
cTemp[4] = rgb +
ImgSize;
//g分量地址
cTemp[5] = cTemp[4] +
ImgSize; //b分量地址
for(y=0; y < height; y++)
for(x=0; x < width; x++)
{
//r分量
temp
= cTemp[0][y*width+x] + (cTemp[2][(y/2)*(width/2)+x/2]-128) *
YuvToRgb[0][2];
cTemp[3][y*width+x] = temp<0 ? 0 : (temp>255 ? 255 :
temp);
//g分量
temp
= cTemp[0][y*width+x] + (cTemp[1][(y/2)*(width/2)+x/2]-128) *
YuvToRgb[1][1]
+ (cTemp[2][(y/2)*(width/2)+x/2]-128) *
YuvToRgb[1][2];
cTemp[4][y*width+x] = temp<0 ? 0 : (temp>255 ? 255 :
temp);
//b分量
temp
= cTemp[0][y*width+x] + (cTemp[1][(y/2)*(width/2)+x/2]-128) *
YuvToRgb[2][1];
cTemp[5][y*width+x] = temp<0 ? 0 : (temp>255 ? 255 :
temp);
}
//写到BMP文件中
sprintf(BmpFileName,
"test.bmp", file, n);
WriteBmp(width, height, cTemp[3],
cTemp[4], cTemp[5], BmpFileName);
free(yuv);
free(rgb);
return n;
}
//入口 没啥东西
void
main()
{
int i=1;
// for( i=0;
i<260; i++)
Convert("test.cif",
WIDTH, HEIGHT, i);//调用上面的Convert,获取文件的第i帧
}
//写BMP 不必关注
int WriteBmp(int width, int height, unsigned char
*R,unsigned char *G,unsigned char *B, char
*BmpFileName)
{
int x=0;
int
y=0;
int i=0;
int
j=0;
FILE *fp;
unsigned char
*WRGB;
unsigned char *WRGB_Start;
int yu = width*3%4;
int BytePerLine = 0;
yu = yu!=0 ? 4-yu : yu;
BytePerLine
= width*3+yu;
if((fp = fopen(BmpFileName, "wb")) ==
NULL)
return
0;
WRGB = (unsigned
char*)malloc(BytePerLine*height+54);
memset(WRGB, 0,
BytePerLine*height+54);
//BMP头
WRGB[0] = ‘B‘;
WRGB[1] =
‘M‘;
*((unsigned int*)(WRGB+2)) =
BytePerLine*height+54;
*((unsigned int*)(WRGB+10)) =
54;
*((unsigned int*)(WRGB+14)) =
40;
*((unsigned int*)(WRGB+18)) =
width;
*((unsigned int*)(WRGB+22)) =
height;
*((unsigned short*)(WRGB+26)) =
1;
*((unsigned short*)(WRGB+28)) =
24;
*((unsigned short*)(WRGB+34)) =
BytePerLine*height;
WRGB_Start = WRGB + 54;
for(y=height-1,j=0; y >= 0;
y--,j++)
{
for(x=0,i=0; x<width; x++)
{
WRGB_Start[y*BytePerLine+i++] =
B[j*width+x];
WRGB_Start[y*BytePerLine+i++] =
G[j*width+x];
WRGB_Start[y*BytePerLine+i++] =
R[j*width+x];
}
}
fwrite(WRGB, 1, BytePerLine*height+54,
fp);
free(WRGB);
fclose(fp);
return 1;
}
转自:http://ctfysj.blog.hexun.com/14194936_d.html
(转)RGB 与 YUV420 相互转换,布布扣,bubuko.com
原文地址:http://www.cnblogs.com/tiancun/p/3768502.html