BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

图片即时优化的三种简单解决方案

| 作者 Gilad David Maayan 关注 0 他的粉丝 ,译者 谢丽 关注 11 他的粉丝 发布于 2017年9月21日. 估计阅读时间: 22 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

本文要点

  • Web页面中的图片往往是页面加载缓慢的最主要原因;
  • 图片优化很复杂,涉及大小调整、裁剪、格式转换及质量参数微调;
  • 如今,有的云服务可以即时优化图片,极大地改善用户浏览包含图片的Web页面时的体验;
  • 云服务提供了简单的API用于操作图片;
  • 读者可以立即应用其中的一项服务,毫不费力地提升网站性能。

图片往往是导致页面加载缓慢的最主要原因。一些研究表明,以兆字节计的Web页面还在稳步增加,图片更是其中最大的部分。显然,大部分网站可以通过图片优化大幅提升性能。

本文将介绍如何使用Kraken.ioCloudinaryImgix三种不同的云服务,借助几行代码轻松实现图片的自动优。你可以立即使用这些服务中的一种减少网站图片文件的大小,大幅提高页面加载速度和带宽使用率。

图片优化涉及哪些方面?

在开始介绍如何自动优化图片之前,首先让我们了解下图片优化的基本要素:图片大小及调整、图片格式、图片质量或压缩。下面是图片优化的常见步骤,每一步对应其中一项要素:

  • 根据图片在Web页面上实际占用的空间调整图片大小及裁剪图片。我们认为,在浏览器端调整大小是不好的做法,因为那会强制用户无谓地下载大图片。
  • 将图片转换成最恰当的文件格式。对于不同类型的图片,情况可能会有所差别;在某些情况下,PNG是最优的格式,而在其他情况下则是JPEG。如果用户有一个现代浏览器,则可以使用那个浏览器支持的新文件格式。例如,只有Chrome支持的WebP格式,或者IE9及以上版本支持的JPEG-XR格式。
  • 优化目标文件格式的压缩。例如,JPEG图片有一个质量设置。指定一个小于100%的质量百分比会压缩图片,但同时也会降低视觉品质。优化的艺术是找出不会导致可见质量损失的最高压缩水平(图片质量确实降低了,但只是轻微的,所以人根本注意不到)。确切的压缩阈值会因图片和格式的不同而有所差别。

另外一种优化是去掉文件中不必要的元数据。大部分照片都包含相机和图形应用存储的元数据,这增加了图片的大小,而且终端用户并不需要。本文将要介绍的所有图片优化服务都会同时去掉这类元数据。

上述步骤非常耗时,而且需要具备专业知识才能达到理想的效果。对于只有几张图片的网站而言,也许可以手工优化图片。不过,在现代网站上,一个页面就有几十或者几百张图片,所以,自动化是有必要的。

首先让我们看下如何手工优化图片。然后,我们将向你展示如何使用其中每一种云图片服务自动实现同样的优化。

下面是参考图片。这是一个2048 X 1365像素的PNG文件,大小为3975KB

图片来源:Marika Mariani on Flickr

为了让情况更复杂一些并充分利用不同工具的功能,我们假设这个横向图片需要刚好放入网页上用于放置肖像的纵向区域。下面是示例Web网页,借用了Wikipedia上的Parrots条目:

(点击查看大图)

为了优化这个图片并将其放到网页上,我们需要执行以下步骤:

  • 调整图片大小并进行裁剪,保证鹦鹉在可用区域里可见,而又不损失原始图片的长宽比。图片会明显变小。

  • 从PNG转换成一个对这个图片而言更有效的文件格式,如JPEG。
  • 压缩图片,减少文件大小,而又不降低图片的视觉品质。

每个步骤都会明显减少文件大小,而又不会在视觉上降低质量。总之,如果我们调整图片大小,转换到一个更精简的文件格式,优化该格式的压缩参数,那么结果图片会是原始图片的一小部分。

现在让我们看下,如何使用三种图片管理服务的其中一种自动实现这种转换,并且看下它们在每个阶段可以将文件缩小多少。

请记住:这不是一个基准。图片内容不同,构图不同,优化后的文件大小可能会有差异。因此,这不是在对不同服务的有效性进行绝对测试,其有效性可能会因为图片类型的不同而不同。

使用Kraken.io优化图片

Kraken.io是一项专门针对图片优化的云服务。其免费方案提供100MB的图片存储。

Kraken提供一个API,你可以通过编程上传图片,或者提供一个指向该图片的URL。在调用这个API时,你可以给服务发送指令,让其对图片执行特定的优化,并下载优化后的新版本。

下面是使用Kraken优化鹦鹉图片的步骤:

1.注册Kraken账户,安装相关SDK,验证自己的身份,并使用POST请求将图片上传到Kraken。

使用Kraken的PHP SDK,上传代码如下:

$kraken = new Kraken("your-api-key", "your-api-secret");

$params = array(
    "file" => "/path/to/image/parrot.jpg",
    "wait" => true
);

$data = $kraken->upload($params);

2.上述代码只是上传图片。我们需要将图片大小调整到要求的尺寸(190 X 270 px),同时,我们还需要裁剪图片,以便我们可以把注意力集中在鹦鹉上,而又不损失长宽比;我们不能只是按照尺寸要求拉伸图片,因为那会使图片失真。

为了调整图片大小及裁剪,我们将修改上述代码,增加一些新参数。"strategy" => "fit"是指将图片大小调整到要求的尺寸,并保留原来的长宽比。"crop_mode" => "e"或"East"是说图片裁剪要以鹦鹉所在的右侧为重点。

$params = array(
       …
        "resize" => array(
        "width" => 190,
        "height" => 270,
        "strategy" => "fit",
        "crop_mode" => "e"
    )
);

API调用的响应中包含一个URL,你可以通过它下载优化后的文件。它看起来是下面这样:

文件大小已经降至105KB,除了调整大小,还没有做其他任何优化。

注意:在默认情况下,Kraken API会去掉图片的所有元数据,因为,当我们调整文件大小时,它会自动删除元数据,将文件大小降得更低一点。我们考察过的其他服务也是如此。

3.现在,让我们把格式从PNG转换成JPEG:

$params = array(
    …
    "convert" => array(
       "format" => "jpeg",
       "background" => "#ff0000"
    )
)

修改后的API调用会返回一个不同的下载URL,图片格式为JPEG:

文件大小现在降至88KB

4.最后,我们会优化JPEG图片的质量。这是像Kraken这样的图片优化解决方案的亮点所在。Kraken提供了一个简单的参数lossy。把这个参数添加到API调用的图片参数里,我们可以告诉Kraken将JPEG质量将至最低,而这种质量上的差异是人眼感觉不到的。

$params = array(
    …
    "lossy" => true
)

结果看上去和上面的图片非常相似,但JPEG质量降低了:

新文件仅有29KB,比PNG图片调整大小后减少了72%。这只是由图片压缩带来的改善,因为我们之前已经调整了PNG图片的大小。

这是Kraken在不损失视觉感知品质的情况下所能做的最大压缩。原始文件大小为3975KB,也就是说,在文件大小方面,新文件减少为原来的1/137

5.一种更进一步的优化方法是将图片转换成最为优化的WebP文件格式,而不是JPEG。不足之处是,只有Chrome浏览器支持WebP。为此,我们将转换参数替换为webp参数,并保留lossy参数,将WebP图片的大小尽可能将至最低。

$params = array(
    …
    "webp" => true,
    "lossy" => true
)

结果看起来是这个样子(只有在Chrome浏览器上可见)。

最终的WebP文件只有11KB,比调整大小后的PNG文件小89%,是原始文件的1/361

下面是使用Kraken API生成这个结果的完整PHP代码。最后一行代码获取URL下载优化后的图片。

require_once("Kraken.php");

$kraken = new Kraken("your-api-key", "your-api-secret");

$params = array(
    "file" => "/path/to/image/parrot.jpg",
    "wait" => true
    "resize" => array(
        "width" => 190,
        "height" => 270,
        "strategy" => "fit",
        "crop_mode" => "e"
        "webp" => true,
        "lossy" => true
);

$data = $kraken->upload($params);

$result = $data["kraked_url"];

注意:Kraken郑重声明,结果URL不应该直接用在网站上,应用程序应该下载图片,保存在本地,并通过一个本地URL提供。

使用Cloudinary优化图片

Cloudinary是一项执行图片优化的云图片服务,还提供各种各样的图片操作、云存储和CDN分发。Cloudinary的免费方案提供2GB的云存储,75000张图片,每月7500次图片转换。

Cloudinary使用一种不同于Kraken的架构。在Cloudinary中,你将图片上传到永久云存储,然后Cloudinary服务会将图片直接分发给你的网站用户。

一个动态URL语言指定需要的图片操作或优化。当URL中有参数变化了,图片会即时调整,用户会看到调整后的图片。我们考察的另外一项服务Imgix,使用了类似的方法。

下面是使用Cloudinary优化鹦鹉图片的步骤:

1.注册Cloudinary账户,使用管理UI上传图片,或者安装Cloudinary SDK,并使用upload函数。在PHP SDK中,代码类似下面这样:

public static function upload($file, $options = array())

注意:和Kraken不同,我们不用在选项数组中传递图片操作参数,因为图片操作后续是即时完成的。Cloudinary提供了额外的上传选项,包括客户端上传,让用户可以上传他们自己的图片。更多信息,请查看Cloudinary的PHP图片上传文档

2.让我们将图片调整并裁剪至190 X 270px,并保持长宽比不变。

cl_image_tag(
     "parrot.png", 
     array(
          "width"=>190, 
          "height"=>270, 
          "crop"=>"fill",
          "gravity"=>"auto")
     )
)

参数"gravity" => "auto"是Cloudinary的一项特性,即使用对象检测自动定位图片中最突出的的物体上。这是一种扩展性更好的方法,不需要针对每张图片调整参数。

上述代码生成了一个HTML图片标签,指向动态图片URL,例如:

<img src=”http://res.cloudinary.com/agile-seo/image/upload/h_270,w_190,c_fill,g_auto/parrot_marika_mariani.png”>

新文件大小为103KB

3.我们将文件从PNG转换成JPEG。在Cloudinary中,这只需要改变文件扩展名:

cl_image_tag(
     "parrot.jpg", 
     array(
           "width"=>190, 
           ...
     )
)

现在,文件只有27KB了。这已经远远低于我们对于全品质JPEG图片的预期了,这表明,Cloudinary已经对图片进行了某些优化。

4.接下来,我们将通过添加"quality"=>"auto"参数全面优化JPEG质量:

cl_image_tag(
     "parrot.jpg", 
     array(
          …
          "quality"=>"auto"
          )
     )
)

现在,文件大小是15KB,比调整大小后的PNG图片小了85%

总得来说,Cloudinary将原始文件的大小缩减为原来的1/265

5.让我们将图片转换为更优化的文件格式。Cloudinary提供了参数"format"=>"auto",可以根据用户的浏览器动态设置图片格式(将图片即时转换成那种格式)。在Chrome浏览器上会自动生成WebP格式的图片。在新版本的Explorer上会生成JPEG-XR格式的。

请注意:文件扩展名仍然是“.jpg”,但实际上,文件格式是根据图片分析和用户浏览器自动确定的。如果你查看Chrome中的URL并下载图片,你就会看到,图片是WebP格式的。

经过质量优化的WebP格式的图片大小为12KB。Cloudinary的WebP优化在文件大小上比优化后的JPEG小20%。

还有一点需要特别注意,就是Cloudinary通过CDN分发图片。这只是一种为了让用户更快地取回图片的额外优化,不会影响文件大小。

使用Imgix优化图片

Imgix的工作原理与Cloudinary类似:上传图片,然后在你的代码中生成一个动态URL,对图片执行不同的优化。和Cloudinary一样,Imgix是一个全功能的图片管理解决方案,提供很多图片操作、云存储和CDN分发。

Imgix提供了免费试用方案,允许用户基于API进行大约3000次图片操作。

下面是使用Imgix优化鹦鹉图片的步骤:

1.注册Imgix账户。Imgix不支持直接上传图片,因此,我们需要将图片放到一个已有的Web文件夹下,并从Imgix控制板连接过去。然后,就可以通过Imgix子域名访问该图片了,即agileseo.imgix.com/my_image.png。

2.让我们裁剪并调整图片大小。使用Imgix PHP SDK,生成动态图片URL的代码如下:

use Imgix\UrlBuilder;

$builder = new UrlBuilder("demos.imgix.net");
    $params = array(
           "w" => 190, 
           "h" => 270,
           "fit" => "crop",
           "crop" => "edges",
     );
echo $builder->createURL("parrot_marika_mariani.png", $params);

w、h、fit和crop参数调整图片的大小,并聚焦于鹦鹉。Imgix有一个“边缘检测”特性(由"crop" => "edges"激活),在裁剪图片的同时,可以聚焦于图片上最重要的部分。

结果图片的大小为119KB

3.现在,我们将添加参数"fm" => "jpeg",将图片转换成JPEG格式。

结果文件大小为24KB

4.添加参数"auto" => "compress",优化JPEG压缩。

最后,经过优化的JPEG文件大小为13KB,比调整大小后的PNG图片小89%。

5.和Cloudinary一样,Imgix提供了一个参数,可以根据图片和用户的浏览器自动选择最佳图片格式。参数是"auto" => "format"。

WebP格式的文件竟然比压缩过的JPEG大,为24KB。这有点奇怪,但在我们看来,Imgix不允许同时使用compress和format选项(我们试过了,没有效果),因此,当选择auto=format时,Imgix会提供一张WebP图片,但没有优化压缩。

即使不进行WebP压缩,使用JPEG格式,Imgix也可以将文件大小降至1/305

和Cloudinary一样,Imgix通过CDN分发图片,这会额外提升用户取回图片的速度。

结果汇总:图片文件大小缩减了250倍

如上所述,本文不是为了提供一个基准,只是让你对自动化图片优化可以达到怎么样的文件大小缩减有一些认识。

下表汇总了我们使用这三种工具的优化结果。如上所述,虽然文件大小大幅缩减,图片质量有所下降,但所有服务生成的图片在视觉上都相当不错。

(点击放大图像)

有趣的是,对于这张特定的参考图片,Cloudinary和Imgix的JPEG转换非常高效,它们几乎将文件大小降至WebP图片的水平。图片内容、构图和复杂度不同,效果可能会有所差异。

实现图片自动优化的动机很明确:毫不费力地即时缩减图片大小,大幅提升网站的性能。我们考察的三项服务全都非常简单,并且提供了免费试用方案,我们建议你试下这些服务,让你的网站保持良好的状态。

你知道其他自动优化图片的工具或方法吗?或者对于我们考察的服务,你有什么想法吗?请在评论里和我们分享!

关于作者

Gilad David Maayan是一名技术作者,帮助领先的技术品牌把他们的产品介绍给新的受众。他还是Agile SEO的CEO兼联合创始人,他们通过搜索引擎将开发人员、IT领导者和相关内容汇集在一起。

查看英文原文:3 Easy Solutions to Optimize Images on the Fly

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT