使用libjpeg库将yuv420数据转换为jpg图片

使用libjpeg库转换yuv数据 为jpg时的步骤与RGB数据基本相同,对原始代码稍作修改即可使用。
源数据格式, yuv420, 存储格式为 yyyy....uu..vv, 转换成jpg图片文件。
fj.pngyuv.bmp,yuv420测试数据,大小为960*540,  分量排列格式为yyyy....uu..vv..
程序代码:

点击(此处)折叠或打开

  1. int yuv420sp_to_jpg(char *filename, int width, int height, unsigned char *pYUVBuffer)
  2. {
  3.     FILE *fJpg;
  4.     struct jpeg_compress_struct cinfo;
  5.     struct jpeg_error_mgr jerr;
  6.     JSAMPROW row_pointer[1];
  7.     int row_stride;
  8.     int i = 0, j = 0;
  9.     unsigned char yuvbuf[width * 3];
  10.     unsigned char *pY, *pU, *pV;
  11.     int ulen;

  12.     ulen = width * height / 4;

  13.     if(pYUVBuffer == NULL){
  14.         debugE("pBGRBuffer is NULL!\n");
  15.         return -1;
  16.     }

  17.     cinfo.err = jpeg_std_error(&jerr);
  18.     jpeg_create_compress(&cinfo);
  19.     fJpg = fopen(filename, "wb");
  20.     if(fJpg == NULL){
  21.         debugE("Cannot open file %s, %s\n", filename, strerror(errno));
  22.         jpeg_destroy_compress(&cinfo);
  23.         return -1;
  24.     }

  25.     jpeg_stdio_dest(&cinfo, fJpg);
  26.     cinfo.image_width = width;
  27.     cinfo.image_height = height;
  28.     cinfo.input_components = 3;
  29.     cinfo.in_color_space = JCS_YCbCr;
  30.     cinfo.dct_method = JDCT_ISLOW;
  31.     jpeg_set_defaults(&cinfo);


  32.     jpeg_set_quality(&cinfo, 99, TRUE);

  33.     jpeg_start_compress(&cinfo, TRUE);
  34.     row_stride = cinfo.image_width * 3; /* JSAMPLEs per row in image_buffer */
  35.     
  36.     pY = pYUVBuffer;
  37.     pU = pYUVBuffer + width*height;
  38.     pV = pYUVBuffer + width*height + ulen;
  39.     j = 1;
  40.     while (cinfo.next_scanline < cinfo.image_height) {
  41.         /* jpeg_write_scanlines expects an array of pointers to scanlines.
  42.          * Here the array is only one element long, but you could pass
  43.          * more than one scanline at a time if that's more convenient.
  44.          */

  45.         /*Test yuv buffer serial is : yyyy...uu..vv*/
  46.         if(j % 2 == 1 && j > 1){
  47.             pU = pYUVBuffer + width*height + width / 2 * (j / 2);
  48.             pV = pYUVBuffer + width*height * 5 / 4 + width / 2 *(j / 2);
  49.         }
  50.         for(i = 0; i < width; i += 2){
  51.             yuvbuf[i*3] = *pY++;
  52.             yuvbuf[i*3 + 1] = *pU;
  53.             yuvbuf[i*3 + 2] = *pV;

  54.             yuvbuf[i*3 + 3] = *pY++;
  55.             yuvbuf[i*3 + 4] = *pU++;
  56.             yuvbuf[i*3 + 5] = *pV++;
  57.         }

  58.         row_pointer[0] = yuvbuf;
  59.         (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
  60.         j++;
  61.     }

  62.     jpeg_finish_compress(&cinfo);

  63.     jpeg_destroy_compress(&cinfo);
  64.     fclose(fJpg);

  65.     return 0;
  66. }
说明一下,由于yuv420格式问题,我们需要用前两行的y分量共享第一行的uv分量,代码:54-57。
转换效果图如下:
fj.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值