压缩 jpeg 以达到指定目标图像文件大小的算法

Algorithm to compress jpeg to achieve a specified target image file size

我有几个 javascript 库 (angular-ahdin, J-I-C),我可以使用它们来压缩用户上传的图像,然后再将其提交到后端。

我见过的所有库都采用质量参数并使用 jpeg 压缩来缩小文件。根据任何质量值,您在压缩之前不知道生成的图像的文件大小。

我的想法是使用 "binary search" 类型的算法来尝试不同的质量百分比,直到我最终得到一个刚好低于目标最大文件大小的图像。

它将以 50% 的 jpeg 质量开始。如果压缩图像低于目标文件大小,则转到 75% 质量,否则转到 25% 质量,依此类推。它会在保证 6 次迭代内将目标文件大小达到 1% 的粒度,然后我会停止。

假设没有一个库已经有这个功能,有没有比二进制搜索更好的方法?是否有任何图像研究表明种子值优于 50%?

由于 JPEG 算法的工作方式,如果输出大小确实如此关键,您的 'binary search' 方法是唯一可行的方法。 JPEG 的设计根本就没有考虑到这个目的,它使用质量设置来丢弃信息,而不是计算特定目标。

由于压缩率会因图像内容和复杂性而异 WILDLY 也没有比从 50% 开始更好的选择了,您必须分析图像做一个更好的猜测,然后你也可以压缩它。

我看到的对二分搜索唯一可能的改进是使其成为分布式搜索。因此,如果 50% 产生 40KB,75% 产生 80KB,并且您的目标是低于 50KB,那么接下来尝试 (50%+floor(25*1/4)) = 56% 而不是 62.5% 是一个非常安全的赌注。由于 JPEG 压缩率不是质量设置的线性函数,但我怀疑这在现实世界场景中会更有效率。

二进制搜索可能足以解决您的问题,但它隐含地假设压缩文件大小是参数 Q 的线性函数,而事实可能不是。因此,可能会有更好的性能选择。

如果您有要处理的图像类型的代表性样本,您可能需要计算平均 size-as-a-function-of-Q 函数。然后你可以看到最佳起点是什么,以及当你改变 Q 时尺寸变化的速度。

在任何情况下,JPEG 的量化 table 通常计算为标准 IJG table 的 "scaled" 版本。 table T[i] 的条目通常作为 Q 的函数缩放为

S = Q < 50 ? 5000/Q : 200 - 2Q
T_Q[i] = (S*T[i] + 50) / 100

因此,如果您的图书馆采用这种方法,则对 Q >= 50 使用二进制(线性)搜索并针对 Q<50 的情况调整线性搜索可能是有意义的。

最后,如果可以使用JPEG2000等渐进式压缩算法,可以直接将目标码率(等效,压缩后的文件大小)作为参数,就可以避免这个问题。