1. 程式人生 > >使用libjpeg-turbo庫中的TurboJPEG API實現圖片解壓,縮放及壓縮功能

使用libjpeg-turbo庫中的TurboJPEG API實現圖片解壓,縮放及壓縮功能

概述:前一篇部落格中說到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只不過是更高一層的封裝而已。
我們看到速率差不多一致