我有几个javascript库(angular-ahdin,J-I-C),我可以使用它来压缩用户在将其提交到后端之前上传的图像。
我见过的所有库都采用了质量参数并使用jpeg压缩来减少文件。根据任何质量值,您无法在压缩之前知道生成的图像的文件大小。
我的想法是使用"二分搜索"类型算法尝试不同质量百分比,直到我最终得到一个刚好低于目标最大文件大小的图像。
它将以50%的jpeg质量开始。如果压缩图像低于目标文件大小,则转至75%质量,否则转至25%质量,依此类推。它会在保证的6次迭代中将目标文件大小达到1%的粒度,然后我会停止。
假设没有已有此功能的库,有没有比二进制搜索更好的方法?是否有任何图像研究表明种子价值高于50%?
答案 0 :(得分:3)
二进制搜索可能足以解决您的问题,但它隐含地假设压缩文件大小是参数Q的线性函数,它可能不是。因此,可能会有更好的表现选择。
如果您有要处理的图像类型的代表性样本,则可能需要计算平均大小 - 作为Q函数的函数。然后,您可以看到最佳起点是什么,以及当您更改Q时大小的变化速度。
在任何情况下,JPEG的量化表通常被计算为"缩放"标准IJG表的版本。表T [i]的条目通常被缩放为Q的函数
S = Q < 50 ? 5000/Q : 200 - 2Q
T_Q[i] = (S*T[i] + 50) / 100
因此,如果你的库遵循这种方法,那么使用Q> = 50的二进制(线性)搜索并调整Q&lt; 50个案例的线性搜索是有意义的。
最后,如果您可以使用渐进式压缩算法(如JPEG2000),则可以直接避免此问题,因为目标比特率(等效,压缩文件大小)可用作参数。
答案 1 :(得分:2)
由于JPEG算法的工作方式,如果输出大小确实非常重要,那么“二分搜索”方法是唯一可行的方法。 JPEG的设计并没有考虑到这一目的,而是使用质量设置来丢弃信息,而不是针对特定目标进行计算。
由于压缩比会根据图像内容和复杂程度而变化 WILDLY ,因此从50%开始并没有更好的选择,您必须分析图像以做出更好的猜测,然后你也可以压缩它。
我在二进制搜索中看到的唯一可能的改进是使其成为分布式搜索。因此,如果50%产生40KB,75%产生80KB,并且你的目标低于50KB,那么尝试(50%+下限(25 * 1/4))= 56%接下来而不是62.5%是一个相当安全的选择。由于JPEG压缩率不是质量设置的线性函数,但我怀疑这在现实场景中会更有效。