Chinaunix首页 | 论坛 | 博客
  • 博客访问: 35512
  • 博文数量: 6
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2016-02-16 14:07
文章分类
文章存档

2016年(6)

我的朋友

分类: C/C++

2016-09-14 14:01:43

使用libjpeg库转换yuv数据 为jpg时的步骤与RGB数据基本相同,对原始代码稍作修改即可使用。
源数据格式, yuv420, 存储格式为 yyyy....uu..vv, 转换成jpg图片文件。
yuv.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。
转换效果图如下:

阅读(2330) | 评论(0) | 转发(0) |
0

上一篇:ssh port forward

下一篇:没有了

给主人留下些什么吧!~~