如何避免优化已经使用PHP优化的图像?

时间:2012-02-20 02:06:44

标签: php optimization image-processing

我目前正在开发一个PHP应用程序,它从命令行运行以优化Images的文件夹。

PHP应用程序更像是其他Image Optimizer的包装器,它只是迭代目录并抓取所有图像,然后通过适当的程序运行Image以获得最佳结果。

以下是我将使用的程序以及每个程序将用于...

imagemagick确定文件类型并将非动画gif的转换为png
gifsicle优化动画Gif 图片
jpegtran优化 jpg 图片
pngcrush优化 png 图片
pngquant png 图片优化为png8格式
pngout png 图片优化为png8格式

我的问题:对于1-10个图像,一切都运行平稳且相当快,但是,一旦我在一个包含10个或更多图像的较大文件夹上运行,它就变得非常慢。我并没有真正看到一个很好的解决方案,但有一点可以避免重新处理已经优化的图像。因此,如果我有一个包含100个图像的文件夹并优化该文件夹然后添加5个新图像,请重新运行优化程序。然后它必须优化105个图像,我的目标是让它只优化5个更新的图像,因为前100个图像已经被优化。单独使用此功能可以在将新图像添加到图像文件夹时大大提高性能。

我意识到简单的解决方案是在处理后简单地将图像复制或移动到新文件夹,我的问题就是这些简单的解决方案是这些图像用于网络和网站,因此图像通常很难 - 链接到网站源代码并改变图像的路径会使其复杂化并且有时可能会破坏它。

我的一些想法是:将某种文本文件数据库写入图像文件夹,列出已经处理过的所有图像,因此当应用程序运行时,它只会运行在不在的图像上那个文件已经。另一个想法是将文件名标记为在名称中显示某种标识以显示其已被优化,第三种想法是在优化后将每个优化文件移动到最终目标文件夹。想法2和3虽然不好,但因为它们会破坏网站源代码中的所有图像路径链接。

所以,如果你能想到这个问题的一个好的/好的解决方案,请分享一下吗?

4 个答案:

答案 0 :(得分:3)

元数据
优化后,您可以在每个图像的元信息中放置一个标记。首先检查该标志,只有在不存在时才进行。您可以使用 exif_read_data() 来读取数据。写它可能 like this

以上是JPG。 PNG的元数据也可以看看 this question, and this one

我不确定GIF,但你绝对可以 convert them to PNGs ,然后添加元数据...虽然我很确定他们有自己的元信息,因为 meta data extraction tools 允许使用GIF。

数据库支持
另一种解决方案是将有关图像的信息存储在MySQL数据库中。这样,在调整优化时,您可以跟踪何时以及在哪个图像上尝试优化。您可以根据您选择的任何参数选择要优化的图像。您可以为此构建一个管理面板。这种方法可以轻松进行实验。

您还可以结合以上两种方法。

最大文件大小
由于这是为了节省空间,因此您可以让程序仅处理大于特定文件大小的图像。理想情况下,在运行一次压缩器之后,所有图像都将低于此文件大小,之后只会触摸新添加的太大的图像。我不知道这在实现方面有多实用,因为它需要压缩器获得低于某些任意文件大小的任何图像。您可以根据图像大小确定最大文件大小.....

答案 1 :(得分:1)

最简单的方法是查看每张图片最后一次更改的时间。如果在上次运行脚本后更改了图像,则必须在此特定图像上运行该图像。 运行脚本的时间戳可以很容易地保存在一个简短的文本文件中。

答案 2 :(得分:0)

我想到的一个想法是将简单的解决方案与更复杂的解决方案混合在一起。优化图像时,将其移动到单独的文件夹。当访问原始图像文件夹时,让.htaccess文件捕获这些链接并将它们路由到可以查看优化文件夹部分中是否存在相同图像的区域,如果不存在,则优化,移动,然后继续。

我知道我说simple解决方案,这是一个非常复杂的解决方案,但很好的部分是该解决方案将为您的问题提供可扩展的方法。


编辑:还有一件事

我喜欢MySQL数据库的想法,因为您可以添加级别安全性(并非所有图像都可以被所有人查看)如果这是必要的话。但它也使你的链接问题(硬编码的)不是一个问题。由于所有链接都是从db中检索图像的单个文件,因此唯一更改的是获取生成的变量。通过这种方式,您的项目变得更具可扩展性,并且更容易进行设计更改。

答案 3 :(得分:0)

对不起,这很晚,但是由于有一种方法可以解决此问题,而无需创建任何文件,存储任何类型的数据或跟踪任何内容。我以为我会分享解决此类问题的方法。

目标
设置一个幂等解决方案,该解决方案可以有效优化图像,而无需依赖于需要跟踪其当前状态的依赖项。

为什么
这样就可以提供一种真正可移植的解决方案,该解决方案可以在新环境,某种程度上丢失跟踪器的环境或对实际上可以在其中保存哪些文件敏感的环境中工作。

诊断
尽管元数据可能是您首先希望检查此信息的来源,但确实在某些情况下它将不可用,并且元数据本身的性质是任意,例如注释,它们可能会出现并不会以任何方式影响图像。我们想要更具体的东西,这是手头资产的明确描述。理想情况下,您将希望“识别”一个是否经过优化,而执行此操作的方法是查看该图像以查看其是否基于其特征。

策略
优化图像时,将提供各种不同的选项,以达到优化的最终状态。您还将检查这些特征,以得出是否实际上已对其进行优化的结论。

示例
假设我们在脚本中有一个名为optimize(path = '')的函数,并假设优化的一部分执行以下操作:

$ convert /path/to/image.jpg -bit-depth=8 -quality=87% -colors=255 -colorspace sRGB ...

请注意,这些选项是您选择指定的选项,它们将应用于图像,并且是可以稍后查看的属性...

$ identify -verbose /path/to/image.jpg
Image: /path/to/image.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Geometry: 1250x703+0+0
  Colorspace: sRGB <<<<<<
  Depth: 8-bit <<<<<<
  Channel depth:
    Red: 8-bit
    Green: 8-bit
    Blue: 8-bit
  Channel statistics:
    Pixels: 878750
    Red:
        ...
    Green:
        ...
    Blue:
      ...
  Image statistics:
    Overall:
      ...
  Rendering intent: Perceptual
  Gamma: 0.454545
  Transparent color: none
  Interlace: JPEG
  Compose: Over
  Page geometry: 1250x703+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: JPEG
  Quality: 87 <<<<<<
  Properties:
    ...
  Artifacts:
    ...
  Number pixels: 878750

正如您在此处看到的那样,输出实际上具有我想要确定是否应该优化此图像的所有内容,并且在性能方面没有任何损失。

结论
遍历文件夹中的文件列表时,可以根据需要进行多次操作,而不必担心过度优化图像或跟踪任何内容。您只需过滤掉所有不想优化的扩展名,(eg .bmp, .jpg, .png),然后检查它们的统计信息,看看它们是否拥有您的函数首先将应用于图像的属性。如果具有相同的值,请跳过,否则请优化。

高级
如果要获得极高的效率,则应检查计划优化的图像的每个属性,并且在优化执行过程中,将仅应用未应用于命令的选项。

注意
显然,此技术旨在显示一个示例,该示例说明如何准确确定是否需要优化图像。我上面列出的实际选项并不是可以选择的元素的完整范围。有多种可用选项可供选择,您可以根据需要应用和检查尽可能多的选项。