用JpegLib压缩YUV,yuv转化为jpeg格式图像程序源代码

此处的YUV数据指I420,I422应该做一下修改也能用,这个我没有测试。

Jpeg的宽度、和高度可以是任意的,原来在网上找的都只能是16的倍数才行。

下面的函数经过测试可用,有什么问题可以与我联系

 

函数实现如下:

参数说明:

Filename:jpg文件名字

yuvData:输入的yuv缓存地址

quality:压缩质量 1-100

image_width:图像宽度

image_height:图像高度

 

int write_JPEG_file (char * filename, unsigned char* yuvData, int quality,int image_width,int image_height)

{

     struct jpeg_compress_struct cinfo;

 

     struct jpeg_error_mgr jerr;

 

     FILE * outfile;    // target file 

     JSAMPROW row_pointer[1];  // pointer to JSAMPLE row[s] 

     int row_stride;    // physical row width in image buffer

     JSAMPIMAGE  buffer;

 

     unsigned char *pSrc,*pDst;

 

     int band,i,buf_width[3],buf_height[3];

     cinfo.err = jpeg_std_error(&jerr);

 

     jpeg_create_compress(&cinfo);

 

 

     if ((outfile = fopen(filename, "wb")) == NULL) {

         fprintf(stderr, "can't open %s\n", filename);

         exit(1);

     }

     jpeg_stdio_dest(&cinfo, outfile);

 

 

     cinfo.image_width = image_width;  // image width and height, in pixels

     cinfo.image_height = image_height;

     cinfo.input_components = 3;    // # of color components per pixel

     cinfo.in_color_space = JCS_RGB;  //colorspace of input image

 

     jpeg_set_defaults(&cinfo);

 

     jpeg_set_quality(&cinfo, quality, TRUE );

 

     //

     cinfo.raw_data_in = TRUE;

     cinfo.jpeg_color_space = JCS_YCbCr;

     cinfo.comp_info[0].h_samp_factor = 2;

     cinfo.comp_info[0].v_samp_factor = 2;

     /

 

     jpeg_start_compress(&cinfo, TRUE);

 

     buffer = (JSAMPIMAGE) (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo,

                                 JPOOL_IMAGE, 3 * sizeof(JSAMPARRAY)); 

     for(band=0; band <3; band++)

     {

         buf_width[band] = cinfo.comp_info[band].width_in_blocks * DCTSIZE;

         buf_height[band] = cinfo.comp_info[band].v_samp_factor * DCTSIZE;

         buffer[band] = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo,

                                 JPOOL_IMAGE, buf_width[band], buf_height[band]);

     } 

 

     unsigned char *rawData[3];

     rawData[0]=yuvData;

     rawData[1]=yuvData+image_width*image_height;

     rawData[2]=yuvData+image_width*image_height*5/4;

 

     int src_width[3],src_height[3];

     for(int i=0;i<3;i++)

     {

         src_width[i]=(i==0)?image_width:image_width/2;

         src_height[i]=(i==0)?image_height:image_height/2;

     }

 

     //max_line一般为16,外循环每次处理16行数据。

     int max_line = cinfo.max_v_samp_factor*DCTSIZE; 

     for(int counter=0; cinfo.next_scanline < cinfo.image_height; counter++)

     {   

         //buffer image copy.

         for(band=0; band <3; band++)  //每个分量分别处理

         {

              int mem_size = src_width[band];//buf_width[band];

              pDst = (unsigned char *) buffer[band][0];

              pSrc = (unsigned char *) rawData[band] + counter*buf_height[band] * src_width[band];//buf_width[band];  //yuv.data[band]分别表示YUV起始地址

 

              for(i=0; i <buf_height[band]; i++)  //处理每行数据

              {

                   memcpy(pDst, pSrc, mem_size);

                   pSrc += src_width[band];//buf_width[band];

                   pDst += buf_width[band];

              }

         }

         jpeg_write_raw_data(&cinfo, buffer, max_line);

     }

 

 

     jpeg_finish_compress(&cinfo);

 

     fclose(outfile);

 

     jpeg_destroy_compress(&cinfo);

 

     return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
下面是一个使用libjpeg库将YUV420p压缩JPEG格式的C++代码示例: ```cpp #include <stdio.h> #include <jpeglib.h> void compress_yuv_to_jpeg(unsigned char* yuv, int width, int height, int quality, const char* filename) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE* outfile = fopen(filename, "wb"); if (!outfile) { fprintf(stderr, "Failed to open output file.\n"); return; } cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; // YUV420p是3个颜色分量 cinfo.in_color_space = JCS_YCbCr; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); JSAMPROW row_pointer[1]; int row_stride; jpeg_start_compress(&cinfo, TRUE); row_stride = width * 3; while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = &yuv[cinfo.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); fclose(outfile); jpeg_destroy_compress(&cinfo); } int main() { // 假设你已经将YUV420p数据存储在unsigned char* yuv中 unsigned char* yuv; int width, height; int quality = 80; // JPEG质量设置为80 const char* filename = "output.jpg"; // 假设你已经设置了yuv的宽度和高度 compress_yuv_to_jpeg(yuv, width, height, quality, filename); return 0; } ``` 这段代码使用libjpeg库中的函数和结构体来进行压缩。它将YUV420p数据写入到一个JPEG文件中,你可以通过调整quality参数来控制JPEG压缩质量。请确保你已经安装了libjpeg库并在编译时链接到对应的库文件。 注意:这只是一个简单的示例代码,实际使用中可能需要更多的错误处理和输入验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值