使用libjpeg-turbo库中的TurboJPEG API实现图片解压,缩放及压缩功能

来源:互联网 发布:一句话笑话知乎 编辑:程序博客网 时间:2024/06/14 18:29

概述:前一篇博客中说到libjpeg-turbo的使用,有一些错误也在前篇博客中纠正了,现在呢,就用TurboJPEG API实现图片的解压,缩放,压缩。

1,直接上代码(简单粗暴,重要代码都加了注释,我就不多费口舌了)

#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include <unistd.h>#include <sys/stat.h>#include <turbojpeg.h>typedef unsigned char uchar;typedef struct tjp_info {  int outwidth;  int outheight;  unsigned long jpg_size;}tjp_info_t;/*获取当前ms数*/static int get_timer_now (){    struct timeval now;    gettimeofday(&now, NULL);    return(now.tv_sec * 1000 + now.tv_usec / 1000);}/*读取文件到内存*/uchar *read_file2buffer(char *filepath, tjp_info_t *tinfo){  FILE *fd;  struct stat fileinfo;  stat(filepath,&fileinfo);  tinfo->jpg_size = fileinfo.st_size;  fd = fopen(filepath,"rb");  if (NULL == fd) {    printf("file not open\n");    return NULL;  }  uchar *data = (uchar *)malloc(sizeof(uchar) * fileinfo.st_size);  fread(data,1,fileinfo.st_size,fd);  fclose(fd);  return data;}/*写内存到文件*/void write_buffer2file(char *filename, uchar *buffer, int size){  FILE *fd = fopen(filename,"wb");  if (NULL == fd) {    return;  }  fwrite(buffer,1,size,fd);  fclose(fd);}/*图片解压缩*/uchar *tjpeg_decompress(uchar *jpg_buffer, tjp_info_t *tinfo){  tjhandle handle = NULL;  int img_width,img_height,img_subsamp,img_colorspace;  int flags = 0, pixelfmt = TJPF_RGB;  /*创建一个turbojpeg句柄*/  handle = tjInitDecompress();  if (NULL == handle)  {    return NULL;  }  /*获取jpg图片相关信息但并不解压缩*/  int ret = tjDecompressHeader3(handle,jpg_buffer,tinfo->jpg_size,&img_width,&img_height,&img_subsamp,&img_colorspace);  if (0 != ret) {    tjDestroy(handle);    return NULL;  }  /*输出图片信息*/  printf("jpeg width:%d\n",img_width);  printf("jpeg height:%d\n",img_height);  printf("jpeg subsamp:%d\n",img_subsamp);  printf("jpeg colorspace:%d\n",img_colorspace);  /*计算1/4缩放后的图像大小,若不缩放,那么直接将上面的尺寸赋值给输出尺寸*/  tjscalingfactor sf;  sf.num = 1;  sf.denom = 4;  tinfo->outwidth = TJSCALED(img_width, sf);  tinfo->outheight = TJSCALED(img_height, sf);  printf("w:%d,h:%d\n",tinfo->outwidth,tinfo->outheight);  /*解压缩时,tjDecompress2()会自动根据设置的大小进行缩放,但是设置的大小要在它的支持范围,如1/2 1/4等*/  flags |= 0;  int size = tinfo->outwidth * tinfo->outheight * 3;  uchar *rgb_buffer = (uchar *)malloc(sizeof(uchar) * size);  ret = tjDecompress2(handle, jpg_buffer, tinfo->jpg_size, rgb_buffer, tinfo->outwidth, 0,tinfo->outheight, pixelfmt, flags);  if (0 != ret) {    tjDestroy(handle);    return NULL;  }  tjDestroy(handle);  return rgb_buffer;}/*压缩图片*/int tjpeg_compress(uchar *rgb_buffer, tjp_info_t *tinfo, int quality, uchar **outjpg_buffer, unsigned long *outjpg_size){  tjhandle handle = NULL;  int flags = 0;  int subsamp = TJSAMP_422;  int pixelfmt = TJPF_RGB;  /*创建一个turbojpeg句柄*/  handle=tjInitCompress();  if (NULL == handle) {    return -1;  }  /*将rgb图或灰度图等压缩成jpeg格式图片*/  int ret = tjCompress2(handle, rgb_buffer,tinfo->outwidth,0,tinfo->outheight,pixelfmt,outjpg_buffer,outjpg_size,subsamp,quality, flags);  if (0 != ret) {    tjDestroy(handle);    return -1;  }  tjDestroy(handle);  return 0;}/*测试程序*/int tj_test(){  tjp_info_t tinfo;    char *filename = "./test.jpg";    int start = get_timer_now();  /*读图像*/    uchar *jpeg_buffer = read_file2buffer(filename,&tinfo);    int rend = get_timer_now();    printf("loadfile make time:%d\n",rend-start);    if (NULL == jpeg_buffer) {        printf("read file failed\n");        return 1;    }    int dstart = get_timer_now();  /*解压缩*/    uchar *rgb = tjpeg_decompress(jpeg_buffer,&tinfo);    if (NULL == rgb) {        printf("error\n");    free(jpeg_buffer);    return -1;    }    int dend = get_timer_now();    printf("decompress make time:%d\n",dend-dstart);    uchar *outjpeg=NULL;    unsigned long outjpegsize;    int cstart = get_timer_now();  /*压缩*/    tjpeg_compress(rgb,&tinfo,80,&outjpeg,&outjpegsize);    printf("out jpeg size = %lu\n",outjpegsize);    int cend = get_timer_now();    printf("compress make time:%d\n",cend-cstart);    char *outfile = "./tjout.jpg";    int wstart = get_timer_now();    write_buffer2file(outfile,outjpeg,outjpegsize);    int wend = get_timer_now();    printf("write file make time:%d\n",wend-wstart);    int end = get_timer_now();    printf("tj all make time:%d\n",end-start);  free(jpeg_buffer);  free(rgb);  return 0;}int main(){    tj_test();}

2,我们看下运行结果和上篇中使用libjpeg-turbo中的libjpeg API实现的相同功能速度对比。我们可以看到花费的时间基本没啥大差别,因为他们都是基于SIMD实现,TurboJPEG只不过是更高一层的封装而已。
我们看到速率差不多一致

3,TurboJPEG的API的官方文档地址:TurboJPEG-API Guide