核心代码调整dct系数,调整量化表,再编码jpeg,用butteraugli跟原图比较,看相似度是否过关,不过关的话,再做调整,不断重复这个循环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| for (int downsample = force_420; downsample <= try_420; ++downsample) { JPEGData jpg = jpg_in; RemoveOriginalQuantization(&jpg, q_in); OutputImage img(jpg.width, jpg.height); img.CopyFromJpegData(jpg); if (downsample) { DownsampleImage(&img); img.SaveToJpegData(&jpg); } int best_q[3][kDCTBlockSize]; memcpy(best_q, q_in, sizeof(best_q)); if (!SelectQuantMatrix(jpg, downsample != 0, best_q, &img)) { for (int c = 0; c < 3; ++c) { for (int i = 0; i < kDCTBlockSize; ++i) { best_q[c][i] = 1; } } } img.CopyFromJpegData(jpg); img.ApplyGlobalQuantization(best_q);
if (!downsample) { SelectFrequencyMasking(jpg, &img, 7, 1.0, false); } else { const float ymul = jpg.components.size() == 1 ? 1.0f : 0.97f; SelectFrequencyMasking(jpg, &img, 1, ymul, false); SelectFrequencyMasking(jpg, &img, 6, 1.0, true); } }
|
重点函数解析1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| Process(params, &stats, rgb, xsize, ysize, &out_data) params: 命令行参数,压缩质量参数 status: 处理的过程状态。 rgb: 原始图像rgb。
EncodeRGBToJpeg(rgb, w, h, &jpg) 把rgb转换成yuv444, 然后做DCT变换,做量化,量化表全是1, 再把结果写入jpg。
ProcessJpegData(params, jpg, comparator.get(), &out, stats); params: 命令行参数,压缩质量参数 jpg: 原图rgb EncodeRGBToJpeg出来的jpg comparator.get() 根据rgb初始化后的ButteraugliComparator out: 最终jpeg输出。 stats: 处理状态。
SelectFrequencyMasking(jpg, &img, 7, 1.0, false) jpg: 原图rgb EncodeRGBToJpeg出来的jpg img: 传址进去, 最终结果输出出来
|
|