YUV格式理解
- Y代表亮度信号,UV代表色度信号。
- YUV444色度信号分辨率最高。每一个像素都有对应的色度与亮度。
- 对于YUV411 YUV420 YUV 422这些都是消减了色度。
- YUV422:4个点亮度,就有2个点U和2点V。
- YUY2/YUYV:每个像素都保留了Y分量。四个字节表示2个像素点。如1920x1080图片的文件大小为1920x1080x2=4M
图片数据流存储理解
YUV2数据流顺序: Y0 U0 Y1 V0 Y2 U2 Y3 V2
UYVY数据流顺序: U0 Y0 V0 Y1 U2 Y2 V2 Y3
libjpeg库函数理解
uint32_t yuv420sp_to_jpg(int width, int height, unsigned char *inputYuv,unsigned char *outJpeg)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
int i = 0, j = 0;
unsigned char *pY, *pU, *pV;
unsigned char yuvbuf[width * 3];
unsigned long outSize;
cinfo.err = jpeg_std_error(&jerr);//用于错误信息
jpeg_create_compress(&cinfo); //初始化压缩对象
jpeg_mem_dest(&cinfo, &outJpeg, &outSize);
cinfo.image_width = width;//设置输入图片宽度
cinfo.image_height = height;//设置图片高度
cinfo.input_components = 3;
cinfo.in_color_space = JCS_YCbCr;//设置输入图片的格式,支持RGB/YUV/YCC等等
cinfo.dct_method = JDCT_FLOAT;
jpeg_set_defaults(&cinfo);//其它参数设置为默认的!
jpeg_set_quality(&cinfo, 40, TRUE);//设置转化图片质量,范围0-100
jpeg_start_compress(&cinfo, TRUE);
pY = inputYuv ;
pU = inputYuv +1 ;
pV = inputYuv + 3;
j = 1;
while (cinfo.next_scanline < cinfo.image_height) {
int index = 0;
for (i = 0; i < width; i += 2){//输入的YUV图片格式为标准的YUV444格式,所以需要把YUV420转化成YUV444.
yuvbuf[index++] = *pY;
yuvbuf[index++] = *pU;
yuvbuf[index++] = *pV;
pY += 2;
yuvbuf[index++] = *pY;
yuvbuf[index++] = *pU;
yuvbuf[index++] = *pV;
pY += 2;
pU += 4;
pV += 4;
}
row_pointer[0] = yuvbuf;
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);//单行图片转换压缩
j++;
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
return (uint32_t)outSize;
}
运行示例
下载示例链接(运行环境VS2013):https://download.youkuaiyun.com/download/fengweibo112/10971728
运行过后,在工程目录下可以看到输出的jpeg图片。