libjpeg实现YUV转jpeg

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.csdn.net/download/fengweibo112/10971728
运行过后,在工程目录下可以看到输出的jpeg图片。

你可能感兴趣的:(应用总结)