【问题标题】:How to avoid Optimizing images that are already optimized with PHP?如何避免优化已经用 PHP 优化的图像?
【发布时间】:2012-03-10 10:52:03
【问题描述】:

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

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

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

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

我的问题:使用 1-10 张图片,一切运行顺利且相当快,但是,一旦我在包含 10 张或更多图片的较大文件夹上运行,它就会变得非常慢。我真的没有看到一个很好的解决方案,但有一点会有所帮助,那就是避免重新处理已经优化的图像。因此,如果我有一个包含 100 个图像的文件夹,并且我优化了该文件夹,然后添加了 5 个新图像,请重新运行优化器。然后它必须优化 105 个图像,我的目标是让它只优化 5 个较新的图像,因为之前的 100 个图像已经被优化。将新图像添加到图像文件夹时,仅此一项就会大大提高性能。

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

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

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

【问题讨论】:

    标签: php optimization image-processing


    【解决方案1】:

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

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


    编辑:还有一件事

    我喜欢 MySQL 数据库的想法,因为您可以添加一个级别的安全性(并非所有人都可以查看所有图像)如果那当然是需要的话。但这也使您的链接问题(硬编码问题)不再是一个问题。由于所有链接都是从数据库中检索图像的单个文件,并且唯一更改的是获取生成的变量。这样一来,您的项目的可扩展性就会显着提高,并且更容易进行设计更改。

    【讨论】:

    • .htaccess 重定向并不是一个可怕的想法,但从长远来看,这种做法不会损害服务器性能吗?至于使用 MySQL DB 存储图像甚至图像路径在我的情况下似乎不是一个好主意。我计划在我建立的每个网站上都使用它,所以我看不到只有这样的图像有一个数据库,这似乎不是一个好主意,性能明智,这就是我优化图像以获得最大效果的全部目的性能我可以
    • 如果没有安全要求,那你就好了。只要有一个好的隐私政策。
    【解决方案2】:

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

    以上内容适用于 JPG。 PNG 的元数据也可以查看 this question, and this one

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

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

    以上两种方法也可以结合使用。

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

    【讨论】:

    • 这实际上是我的第一个想法,但我相信这仅适用于 jpg 图像?在大多数情况下,我的大多数网络图像都将是 png 和 gif 或至少转换为这些,还有一些优化我认为实际上删除了 exif 数据以节省空间。我不能 100% 确定我刚才所说的话,所以我可能是错的,但如果我是对的,这就是为什么我认为这行不通。另外我想避免使用数据库,除非它是某种单文件数据库来列出可以包含在图像文件夹中的文件
    • @jason - PNG 也有元数据。我添加了两个指向答案的链接。
    • 感谢您的跟进,经过更多研究,我有点倾向于拥有某种数据库/文件。最好是位于图像文件夹中的文件,该文件可以列出已经处理的图像,然后只在未优化的图像上运行,在运行结束时,它将更新此列表文件以包含刚刚处理的图像文件处理。我的主要原因是,如果有数百个文件,则必须读取所有这些文件的部分内容才能获取 exif 和元数据,我认为文件/数据库可能会快一点。对这种方法有什么想法吗?
    • 我希望避免使用 MySQL,因为最终产品是我想让其他用户使用的东西,它应该是不需要 MySQL 连接的东西,我应该能够简单地为命令行工具提供图像文件夹路径,它将处理图像,因此任何类型的文件或数据库都需要可供任何类型的用户使用,并且包含在图像文件夹中。我认为这可能适合开始一个新问题,更具体地说是在目录中保留正在运行的目录/db/文件文件,所以我会选择你的答案,因为它有最多的选票
    【解决方案3】:

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

    【讨论】:

    • 我喜欢在文件夹中包含一个简单的文本文件以及上次运行日期/时间并根据 +1 检查每个图像的想法
    【解决方案4】:

    抱歉,这已经晚了,但由于有一种方法可以解决此问题,而无需创建任何文件、存储任何类型的数据或跟踪任何内容。我想我会分享我如何解决此类问题的解决方案。

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

    为什么
    这允许一个真正可移植的解决方案,可以在新环境、以某种方式丢失其跟踪器的环境或对您实际可以在其中保存哪些文件很敏感的环境中工作。

    诊断
    尽管元数据可能是您检查此信息的第一个来源,但确实在某些情况下它不可用,并且元数据本身的性质是任意,就像 cmets 一样,它们可以来去,不要以任何方式影响图像。我们想要一些更具体的东西,它是手头资产的明确描述。理想情况下,您希望“识别”一个图像是否经过优化,这样做的方法是查看图像以查看它是否基于其特征。

    策略
    当您优化图像时,您将提供各种不同的选项以达到优化的最终状态。这些正是您要检查的特征,以确定它是否实际上已被优化。

    示例
    假设我们的脚本中有一个名为 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),然后检查它们的统计信息,看看它们是否具有您的函数将首先应用于图像的属性。如果有相同的值,跳过,如果没有,优化。

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

    注意
    这种技术显然是为了展示如何准确确定图像是否需要优化的示例。我上面列出的实际选项并不是可以选择的元素的完整范围。有多种可用选项可供选择,您可以根据需要申请和检查。

    【讨论】:

      猜你喜欢
      • 2018-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      相关资源
      最近更新 更多