2010-03-24 40 views

回答

1

不幸的是,它不能直接完成:

品質因數不直接存儲 在JPEG文件,所以你 無法從 文件中讀取的品質因數。 (來自:Microsoft support頁...)

更詳細地:

在於使用 壓縮存儲在 的JFIF報頭中的圖像的量化表,但JPEG質量 用於生成 量化表的因子不會沿着圖像 存儲,因此原始 JPEG品質因數將丟失。 (從:JPEG Compression Metrics as a Quality Aware Image Transcoding,通過Surendar錢德拉和卡拉施拉特埃利斯)

以上報價是由紙,其中討論的方法來估計壓縮的水平(通過檢查在圖像中使用的量化表) ,但它看起來並不容易實現:有一個例子here這是Image Magick代碼庫的一部分,但它是用C寫的

難懂的一直portedHaxe,它可以編譯成Flash程序,所以可以想象,你可以得到一些工作,但是我恐怕解釋不了我的技能!


編輯:剛剛在SuperUser上發現了一個similar question,它也提到了Image Magick。


編輯:您可能也有興趣在回答this question,其中問到如何獲得圖像的大小,而無需加載整個文件(適用於處理大於閃存能夠處理圖像)。

0

我已經使用了libjpeg的完成這項工作,也許你可以參考我的代碼

#include <stdio.h> 
#include <math.h> 

#include "jpeglib.h" 
#include <setjmp.h> 

static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { 
    16, 11, 10, 16, 24, 40, 51, 61, 
    12, 12, 14, 19, 26, 58, 60, 55, 
    14, 13, 16, 24, 40, 57, 69, 56, 
    14, 17, 22, 29, 51, 87, 80, 62, 
    18, 22, 37, 56, 68, 109, 103, 77, 
    24, 35, 55, 64, 81, 104, 113, 92, 
    49, 64, 78, 87, 103, 121, 120, 101, 
    72, 92, 95, 98, 112, 100, 103, 99 
}; 

int ReadJpegQuality(const char *filename) 
{ 
    FILE * infile = fopen(filename, "rb"); 
    fseek(infile,0,SEEK_END); 
    size_t sz = ftell(infile); 
    fseek(infile,0,SEEK_SET); 
    unsigned char* buffer = new unsigned char[sz]; 
    fread(buffer,1,sz,infile); 
    fclose(infile); 
    struct jpeg_decompress_struct cinfo; 
    struct jpeg_error_mgr jerr; 
    cinfo.err = jpeg_std_error(&jerr); 
    jpeg_create_decompress(&cinfo); 
    jpeg_mem_src(&cinfo,(unsigned char*)buffer,sz); 
    jpeg_read_header(&cinfo, TRUE); 
    int tmp_quality = 0; 
    int linear_quality = 0; 
    const int aver_times = 3; 
    int times = 0; 
    int aver_quality = 0; 
    for(int i=0;i<DCTSIZE2;i++) 
    { 
    long temp = cinfo.quant_tbl_ptrs[0]->quantval[i]; 
    if(temp<32767L&&temp>0) 
    { 
     linear_quality = ceil((float)(temp*100L - 50L)/std_luminance_quant_tbl[i]); 
     if(linear_quality==1) tmp_quality = 1; 
     else if(linear_quality==100) tmp_quality = 100; 
     else if(linear_quality>100) 
     { 
     tmp_quality = ceil((float)5000/linear_quality); 
     } 
     else 
     { 
     tmp_quality = 100 - ceil((float)linear_quality/2); 
     } 
     aver_quality += tmp_quality; 
     if(aver_times==++times) 
     { 
     aver_quality /= aver_times; 
     break; 
     } 
    } 
    } 
    jpeg_destroy_decompress(&cinfo); 
    return aver_quality; 
} 

int main(int argc,char** argv) 
{ 
    printf("quality: %d\n",ReadJpegQuality("test1.jpg")); 
    return 0; 
} 

這種方法是使用libjpeg的讀取JPG文件的量化表,然後使用量化表計算出的質量參數。