如何根据文件大小限制确定PNG图像尺寸?

5
如果一个应用程序有业务逻辑,规定24位PNG文件的大小不能超过250KB,那么有可能预测出该图像在最大宽度和高度下仍可满足250KB的要求吗?
由于颜色深度、alpha通道等有很多变量,所以这是否可能知道?或者说离答案更近一些?

1
虽然你可能会找到一个最大尺寸,但我认为这并不实用,因为如果你将一个非常巨大的实心图像(例如全空白)压缩为PNG格式,得到的PNG文件会非常小。 - gusbro
正确,这是不可能的。你必须将图像写成PNG格式,测量它的大小,然后才能确定。 - Ani
4个回答

7
可能可以实现,但可能没有用。 PNG的zlib压缩具有1032:1的最大压缩比(对于相同字节值的长序列)。因此,压缩后的250 KB大小(忽略包装和其他内容)将是大约250 MB的未压缩大小。对于一个正方形图像,这将是近10000 x 10000像素,每像素三个字节。
请注意,这里另一个答案不可理解地假设使用了最小压缩,这给出了最少的像素数量,例如500 x 333。由于问题要求“图像可以拥有的最大宽度和高度”,因此该答案没有用处。显然,10000 x 10000比500 x 333大。
更新:
基于最小PNG文件的精确计算结果表明,24位像素(以压缩数据中存储的每个像素三个字节为单位)的最大数量是文件大小n字节的函数。
floor(((n - 77) * 8 - 1) / 2) * 86 + 1

因此,对于250 * 1024 = 256,000字节,我们得到88,037,427个像素。 对于一个正方形图像,大约是9383 x 9383像素。


3
在解决了同样的问题后,我创建了一个有效的解决方案。
假设压缩对于最坏情况没有效果,每个像素将存储8个字节的数据,其中每个R、G、B和A各占2个字节。因此,100x100像素的图像最大为80,000字节,再加上一些微不足道的元数据。
在进行这些简单的计算之后,我进行了许多关于斑马纹多色照片的实验,但是我从未得到超过那个大小的三分之一,即每10k像素约30kb。
凭借这些知识,我编写了一个递归函数,将输入的png图像缩小10%,直到其大小低于限制,并保留正确的尺寸。然后,我在目标对象上还原它的结果图像。这产生了最佳的质量,正确的大小,并且在CPU上几乎没有额外的负载(因为缩小在实践中从未发生)。
这是我依赖的png规范: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html 您也可以查看维基百科文章: https://en.wikipedia.org/wiki/Portable_Network_Graphics

2

您可以假设 PNG 文件未经压缩,从而预测其可能的最大大小。将宽度 * 高度 * 3 相乘并加上一定的标题开销。

为了更好地预测,可以测量应用程序中大量典型的 PNG 文件,并找到实际文件大小与上述预测之比最大的一个。使用此比率或稍大些的数字来估计任何其他图像的大小。

这仍然不能保证结果会足够小,您只能通过尝试编写编码图像来确定。但对于除了最恶劣情况之外的所有情况,这应该已经足够了。

编辑:如果不清楚,您可以反向计算并从最大文件大小获取图像尺寸。假设 wh 是可接受的最大宽度和高度,aw/h 的纵横比率,r 是上述发现的文件大小/图像大小之比:

w = sqrt((250K * a) / (r * 3))
h = w / a

所以举个例子,如果a等于1.5,r等于0.5,您的尺寸将是500 x 333。

1
问题不是在给定图像中找到最大的PNG文件,而是在给定PNG文件大小时找到最大的图像。 - Mark Adler
2
@MarkAdler,一旦你知道这两者之间的关系,反转方程就变得微不足道了。 - Mark Ransom
1
不行,因为它们是两种完全不同的关系。你的答案是对错误问题的正确方法。颠倒这种关系完全是对实际问题的错误回答。要得到你极其错误的答案,你必须假设最小的压缩量。要得到正确的答案,你必须假设最大的压缩量来回答正确的问题。 - Mark Adler
1
@MarkAdler,如果你无法准确计算结果,那么你必须进行估算。如果有硬性限制,你必须保守地估算。我的指示是找到压缩最严重的图像,并以此作为指导。使用最大压缩量将是一个错误。 - Mark Ransom
1
哇,好的。我放弃了。请仔细阅读问题。 - Mark Adler

-1

如果您将一个巨大的空白文件保存为PNG格式,它的大小会非常小,因为PNG压缩技术的原因,但这并不可行。

如果您想要向用户提供图像尺寸,请更改您的业务逻辑,接受基于图像尺寸而不是文件大小的图像。


10000乘以10000并不太荒谬,可以看一下计算出结果的答案。 - alan2here

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接