如何使用特定文件大小保存图像?

时间:2010-11-23 00:45:26

标签: php image image-processing image-compression

我正在构建一个PHP系统,用户可以创建视觉上复杂的图像,最终要求 50kB或更低

用户可以选择将文本打印到37个模板图像中的一个上,因此结果是单个平面图像。

文本可以是任何颜色,也可以是多种字体之一。这意味着最终图像可能非常复杂且不可预测(图像尺寸除外)。

然后我要求最终图像文件大小不大于50kB (这是外部要求,不能更改)。

最后一项要求(同样是外部)是图片格式必须为 .jpeg,.png或.gif

我查看了GraphicsMagick文档,但找不到任何能够设置文件大小并且自动计算压缩的内容。

我已经考虑通过compress-> save->测试循环以编程方式执行此操作,但是我可以想象这将是非常耗费处理器的,因为我无法事先根据压缩来计算文件大小。这就是为什么我要问看看问题是否已经在GraphicsMagick中解决了。

修改

要明确为什么有外部要求:

用户将利用此系统创建一个平面图像,然后将其保存到PC上。然后将此图片上传到Adroll,以便在重定向广告系列中使用。

以下是图片上的Adroll's requirements。我的系统仅提供728x90,300x250和120x600图像尺寸。

编辑 2010年11月27日

由于GraphicsMagick似乎无法做到这一点,我愿意研究其他解决方案,例如直接与可能提供功能的压缩库(libpng等)接口。

作为最后的手段,我甚至可以查看可以实现此目的并自行实现的算法。


作为类比,对于那些倾向于那些的人:

我追求A *的搜索:它有一个明确的起点/终点,并在最快的时间内找到最佳路线。

我希望避免的是广度/深度优先搜索:明确的起点/终点,但一旦找到局部最小值,可能无法达到最优解,并且有可能在计算上完全爆发。< / p>

9 个答案:

答案 0 :(得分:11)

由于没有办法压缩到我所知道的目标大小,我建议寻找间接解决方案:

  1. 做一些快速统计(可能通过压缩大量具有不同JPEG压缩因子的图像)来找出给定质量水平的平均压缩尺寸及其标准偏差。
  2. 接受图像时,请尝试以合适的质量进行压缩。如果生成的文件太大,请降低质量并重试。可选地,如果结果太小,也可以提高质量。
  3. 当结果图像“接近”目标尺寸时停止,但更小。
  4. 详细说明第2步中的数学:

    如果您选择起始质量,使您的平均计算尺寸+ 3 *标准偏差<1。你的目标大小,然后99.7%的压缩将在第一次尝试时产生一个适当的小文件(假设压缩大小的正态分布)。

    您可以根据需要调整起始质量和增加或减少它的逻辑,在较少的服务器负载和接近最大大小的文件之间取得平衡(“更好地利用”您的限制)。

答案 1 :(得分:9)

查看以下包裹:

http://www.phpclasses.org/package/3810-PHP-Optimize-images-to-fit-in-a-given-file-size-limit.html

非常酷 - 我说作者值得喝啤酒;)

实际上是61081字节的图像(第一个在图像中显示文件大小的jpeg图像?):

alt text

答案 2 :(得分:1)

是否可以使用GraphicMagick的“-limit disk 50mb”与“-list资源”结合使用,以便您可以在此过程的早期检查(或确实在整个过程中进行调查)并进行调整以适应?

http://www.graphicsmagick.org/GraphicsMagick.html#details-limit

答案 3 :(得分:0)

我不知道如何自动确定图像的结果文件大小 - 这是生成图像的库的任务。除非您自己实施压缩,否则无法预先计算结果大小。

您可以做的是收集统计数据(图像高度和宽度以及文件大小与不同的压缩选项),并根据新数据的数据进行估算。

示例:

  • 50k jpg,100x200压缩30k
  • 100k jpg,100x200压缩60k

- &GT;当你得到一个59k的100x202px图像时,压缩的大小估计大约为35k。

答案 4 :(得分:0)

所以,如果我理解正确的话 - 您正在构建一个允许用户在您提供的模板图像之一上写一些文本的系统。如果这是正确的,为什么要保存图像?您可以通过保存用户操作本身轻松删除50Kb大小限制。您可以执行以下操作 - 保存文本(及其属性和位置)及其所在的模板。

答案 5 :(得分:0)

只有三种方法可以减少任何给定图像的最终尺寸:

  1. 降低分辨率
  2. 降低颜色深度
  3. 降低图像复杂度
  4. 前两个在你的控制之下。如果上传的图像文件大小超过限制,您可以尝试将其缩小到下一个较小的可用大小,看看它是否适合。鉴于你只有3个目标分辨率,这不会太贵。但是如果您需要“大”尺寸,那么您将选择3。

    降低图像复杂度是一个讨厌的野兽。您可以尝试减少像素间“噪声”以产生相同颜色的更大区域,这将非常好地压缩GIF / PNG图像。一个简单的模糊滤镜可以实现这一点,但它也可能破坏图像中任何精细打印/文本的易读性。对于JPG目标,您可以尝试降低压缩质量,但如果将质量降低到太低,这可能会丢弃图像。如果简单的服务器端转换无法处理此问题,那么首先必须由创建它的艺术家重做该图像。

    我能看到的唯一实用的方法就是你提到的压缩 - 保存 - 测试循环。鉴于最终图像相对较小,这对服务器来说不会是那么大的负担。保存gif / png是一种轻量级操作。 JPG压缩需要更多的CPU能力,但同样,对于小图像,现代服务器在一两秒内完成10或20个测试图像应该没有任何问题。

答案 6 :(得分:0)

虽然到达目标文件大小的循环程序化选项似乎是流行的答案,有两种方法使用 .jpeg压缩


Kuo,Chun-ming有专利方法,所以我不确定利用它的商业可行性:

Method and electronic device for adjusting compression ratio of jpeg image

基于这个公式:

log(NSF) = (log(SF1 / SF2) / log(FileSize1 / FileSize2)) * log(Target / FileSize1) + log(SF1)

其中

SF1 is a first compression parameter
SF2 is a second compression parameter
FileSize1 is the size of the image compressed with SF1
FileSize2 is the size of the image compressed with SF2
Target is the target file size
NSF is the target compression parameter.

目前尚不清楚SF1,SF2和NSF是否在0-1或0-100等范围内,并且FileSize1,FileSize2和Target是否为Bytes,KiloBytes等。试验正确的组合在这里找出正确的单位。

<小时/> 第二种方法来自麻省理工学院的Ricky D. Nguyen:

Rate control and bit allocations for JPEG transcoding

他建议在发生压缩时改变用于压缩的数据。此选项可能不太可行,因为它需要修改实际的压缩代码本身。


从这两个示例中,肯定可以保存具有特定目标文件大小的.jpeg文件。

答案 7 :(得分:0)

首先尝试24位.png。如果这适合它将是最好的质量,你就完成了。或者你可以测试一些典型的图像,如果它们都不合适,你可以完全不考虑格式。

对于.gif和.jpg,您需要搜索最合适的内容;没有一个可以用足够的确定性预测,并且这两种算法都不适合于恒定比特率编码。您可以使用二进制搜索来找到最合适的搜索结果。您可以从预定列表中选择压缩因子,以限制您需要执行的测试压缩次数;例如,如果你的.jpg压缩因子列表是4,6,8,12,18,27,44,66,你最多需要进行4次测试压缩。

.gif和paletted .png足够相似,你应该选择一个而忘记另一个。

根据压缩结果在.gif / .png和.jpg之间进行选择会很困难;每个过程引入的工件完全不同。再次,您可能最好将一些测试图像压缩到目标尺寸,并根据眼球测试消除一种或另一种格式。

答案 8 :(得分:0)

或许您正在从错误的角度看问题。通过选择使用PNG并最小化存储在图像中的元数据,您将最小化文件大小。这是因为PNG是一种位图结构。只要GMagick不将文本存储为元数据,它就不会对文件大小产生影响。只有颜色深度(您也可以控制)将影响文件的大小。不过滤文件大小的非交错应与模板大小基本相同。只要模板小于50Kb,你应该没问题。