利用libjpeg库压缩成jpg图像,采用动态内存分配 /linux/c/c++

   利用ibjpeg库进行图片的压缩,经常调用jpeg_stdio_dest(&cinfo,fp/*文件指针*/)函数。由于fp文件是在调用函数之前就分配好了的足够大的内存来存储压缩后的图像,所以经过压缩后的图像大小(单位为kb)即为fp分配的内存大小。因此就会出现分配fp的内存越大就越会浪费空间;但如果分配fp的内存不够大,就会造成压缩崩溃。

   libjpeg图片压缩,只有在压缩结束后才知道具体的内存大小。所以动态的分配内存既不会造成空间浪费,也不会造成压缩崩溃。

   libjpeg库中提供了动态分配内存的函数jpeg_mem_dest(j_compress_ptr cinfo, unsigned char** outbuffer, unsigned long* outSize)。所以在压缩的过程中将jpeg_mem_dest()替换掉jpeg_stdio_dest()就可以弥补上述缺点。

   //jpeg_mem_dest()函数参数说明:

   oubuffer:压缩后的Jpg图像,由函数返回;其内存是在jpeg_mem_dest()函数中申请的,所以压缩完之后需要释放空间,否则造成内存泄露。

   outSize:压缩后图像的字节数,由函数返回。

   注意:可能不同的libjpeg库此函数名不同,有的为jpeg_memio_dest()。在调用前请查看开源库中jdatadst.c此函数名以及具体的参数。 

   //函数调用测试:

   inRgbImg为输入图像    //像素:1600*1200   大小:5.5M

   pOutJpgImg为输出图像  //首先分配的内存为1600*1200*3  输出实际图像的像素: 1600*1200  大小: 290kb 

    int quality = 90;
    struct jpeg_compress_struct cinfoDecodec;
    struct jpeg_error_mgr jerr;
    unsigned char* inImageBuffer;
    unsigned char* outbuffer;
    outbuffer = NULL;
    JSAMPROW row_pointer[1]; 
    int row_stride; 
    unsigned long outSize = 0; 

    inImageBuffer = inRgbImg.bufferPtr; 
    JSAMPROW row_pointer[1]; 
    int row_stride; 
    unsigned long outSize = 0; 
    inImageBuffer = inRgbImg.bufferPtr; 
    cinfoDecodec.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfoDecodec);
    jpeg_mem_dest (&cinfoDecodec, &outbuffer, &outSize);
    cinfoDecodec.image_width = inRgbImg.width; 
    cinfoDecodec.image_height = inRgbImg.height;
  
    cinfoDecodec.input_components = 3;    
    cinfoDecodec.in_color_space = JCS_RGB; 
    jpeg_set_defaults(&cinfoDecodec);
    jpeg_set_quality(&cinfoDecodec, quality, true);
    jpeg_start_compress(&cinfoDecodec, TRUE);
    row_stride = inRgbImg.width * 3; 
    while (cinfoDecodec.next_scanline < cinfoDecodec.image_height) 
    {
        row_pointer[0] = & inImageBuffer[cinfoDecodec.next_scanline * row_stride];
        (void) jpeg_write_scanlines(&cinfoDecodec, row_pointer, 1);        
    }    
    jpeg_finish_compress(&cinfoDecodec);
    
    for(int i = 0; i < outSize; i++)
    {
       (*pOutJpgImg).bufferPtr[i] = outbuffer[i];
    }
  (*pOutJpgImg).bufferSize = outSize;
    jpeg_destroy_compress(&cinfoDecodec); 
    
    if(NULL != outbuffer)
    {
        free(outbuffer);
        outbuffer = NULL;
    }

在这个过程中主要用到了双指针

char* pOutImage //压缩前图片的字节数
void(char** ptr) {
*ptr = (char *)malloc(Size) ; //Size为压缩后图片的字节数
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值