之前蠻好奇當我們要壓 JPEG 檔案的時候
那些 50%, 70%, 90% 的壓縮比是怎麼算出來的
最近看到下面的作法:
if (quality <= 0) quality = 1;
if (quality > 100) quality = 100;
if (quality < 50)
quality = 5000 / quality;
else
quality = 200 - quality*2;
然後再用這個 quality 去 scale JPEG 標準的 quantization table 的每個係數
dct_block[i] = coeff[i] * quality / 100;
也就是說當我們用 50% 去壓的時候,用的才是標準的 quantization table
往上或是往下調壓縮率會根據下面的算法 (scale_factor 就是上面的 quality)
for (i = 0; i < DCTSIZE2; i++) {
temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
/* limit the values to the valid range */
if (temp <= 0L) temp = 1L;
if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
if (force_baseline && temp > 255L)
temp = 255L; /* limit to baseline range if requested */
(*qtblptr)->quantval[i] = (UINT16) temp;
}
當調到 100% 的時候, 每個 quantization table 的值都會是 1
以下是 JPEG 標準的 quantization table 參考值
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
};
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
我看的 source 是 Independent JPEG Group (http://www.ijg.org/) 所提供的
這份程式雖然是 C 寫成的, 可是程式本身卻非常 OO
用 C 的傳統語法, 實作出很多 OO 的概念, 精簡易懂的好程式
=============================================================================
現在的數位相機預設的 quantization table 都非常的小
例如 OLYMPUS C2100UZ 照出來的 quantization table (luminance)
1 1 1 1 1 2 2 2
1 1 1 1 1 2 2 2
1 1 1 1 2 2 3 2
1 1 1 1 2 3 3 2
1 1 1 2 3 4 4 3
1 1 2 3 3 4 5 4
2 3 3 3 4 5 5 4
3 4 4 4 4 4 4 4
另外一台 Canon S45 更誇張, 整個 table 全部都是 1 (也就是 100%)
所以現在數位相機照出來的照片, 其實是傾向幾乎無失真的
转载于:https://my.oschina.net/jerikc/blog/278691