之前蠻好奇當我們要壓 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%) 所以現在數位相機照出來的照片, 其實是傾向幾乎無失真的