使用libjpeg库转换yuv数据 为jpg时的步骤与RGB数据基本相同,对原始代码稍作修改即可使用。
源数据格式, yuv420, 存储格式为 yyyy....uu..vv, 转换成jpg图片文件。
yuv.bmp,yuv420测试数据,大小为960*540, 分量排列格式为yyyy....uu..vv..
程序代码:
-
int yuv420sp_to_jpg(char *filename, int width, int height, unsigned char *pYUVBuffer)
-
{
-
FILE *fJpg;
-
struct jpeg_compress_struct cinfo;
-
struct jpeg_error_mgr jerr;
-
JSAMPROW row_pointer[1];
-
int row_stride;
-
int i = 0, j = 0;
-
unsigned char yuvbuf[width * 3];
-
unsigned char *pY, *pU, *pV;
-
int ulen;
-
-
ulen = width * height / 4;
-
-
if(pYUVBuffer == NULL){
-
debugE("pBGRBuffer is NULL!\n");
-
return -1;
-
}
-
-
cinfo.err = jpeg_std_error(&jerr);
-
jpeg_create_compress(&cinfo);
-
fJpg = fopen(filename, "wb");
-
if(fJpg == NULL){
-
debugE("Cannot open file %s, %s\n", filename, strerror(errno));
-
jpeg_destroy_compress(&cinfo);
-
return -1;
-
}
-
-
jpeg_stdio_dest(&cinfo, fJpg);
-
cinfo.image_width = width;
-
cinfo.image_height = height;
-
cinfo.input_components = 3;
-
cinfo.in_color_space = JCS_YCbCr;
-
cinfo.dct_method = JDCT_ISLOW;
-
jpeg_set_defaults(&cinfo);
-
-
-
jpeg_set_quality(&cinfo, 99, TRUE);
-
-
jpeg_start_compress(&cinfo, TRUE);
-
row_stride = cinfo.image_width * 3; /* JSAMPLEs per row in image_buffer */
-
-
pY = pYUVBuffer;
-
pU = pYUVBuffer + width*height;
-
pV = pYUVBuffer + width*height + ulen;
-
j = 1;
-
while (cinfo.next_scanline < cinfo.image_height) {
-
/* jpeg_write_scanlines expects an array of pointers to scanlines.
-
* Here the array is only one element long, but you could pass
-
* more than one scanline at a time if that's more convenient.
-
*/
-
-
/*Test yuv buffer serial is : yyyy...uu..vv*/
-
if(j % 2 == 1 && j > 1){
-
pU = pYUVBuffer + width*height + width / 2 * (j / 2);
-
pV = pYUVBuffer + width*height * 5 / 4 + width / 2 *(j / 2);
-
}
-
for(i = 0; i < width; i += 2){
-
yuvbuf[i*3] = *pY++;
-
yuvbuf[i*3 + 1] = *pU;
-
yuvbuf[i*3 + 2] = *pV;
-
-
yuvbuf[i*3 + 3] = *pY++;
-
yuvbuf[i*3 + 4] = *pU++;
-
yuvbuf[i*3 + 5] = *pV++;
-
}
-
-
row_pointer[0] = yuvbuf;
-
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
-
j++;
-
}
-
-
jpeg_finish_compress(&cinfo);
-
-
jpeg_destroy_compress(&cinfo);
-
fclose(fJpg);
-
-
return 0;
-
}
说明一下,由于yuv420格式问题,我们需要用前两行的y分量共享第一行的uv分量,代码:54-57。
转换效果图如下:
阅读(7134) | 评论(0) | 转发(1) |