likes
comments
collection
share

聊一聊web图片小知识

作者站长头像
站长
· 阅读数 31

在上家公司做的分享,整理下分享给大家,需要40页的PPT可加V(V798595965)联系(有摸鱼群🐳),or公众号 点击直达回复【图片PPT】即可获取,兄弟姐妹顺便帮小弟点个赞

聊一聊web图片小知识

一、背景

1.1 为什么选这个主题

聊一聊web图片小知识

1.2 带着问题看

  • GIF都糊成马赛克了,为什么还没怎么见过高清的?
  • JPEG 和 JPG有没有区别?什么区别?渐进式图片?
  • PNG为什么透明?
  • 什么是高斯模糊吗?
  • 图片原生支持响应式的方法?
  • 我们可以用<img>标签可以做哪些技术方案?
  • .......

二、图片类型

直接开讲,说到图片类型,大家可能立刻会想到的是jpg,png等,这些都算是图片格式,实际上图片有两种类型:

  • 位图
  • 矢量图

2.1 位图

位图(bitmap)BMP,亦称为点阵图像栅格图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样

聊一聊web图片小知识

2.2 矢量图

矢量图(vector),也称为面向对象图像或绘图图像,在数学上定义为一系列由点连接的线。矢量文件中的图形元素称为对象。每个对象都是一个自成一体的实体,它具有颜色、形状、轮廓、大小和屏幕位置等属性。

简单来说矢量图就像用几何图形来描述一幅图,在矢量图放大时,我们所记录的几何图形的各种角度、形状等并没有改变,所以无论是放大还是缩小,都不会影响矢量图的清晰度。对前端而言,能接触到的就是SVG格式了。

2.3 类型对比

  • 位图的放大质量较差,但是矢量图可以不降低质量地无限放大。

聊一聊web图片小知识

矢量图位图
色彩
空间
转换可随意转为位图转矢量图难度较大,也无法达到高质量
使用场景标识、图标、Logo等简单直接的图像网络中比较丰富的图片中

三、图片压缩

3.1 无压缩

无压缩的图片格式不对图片数据进行压缩处理,能准确地呈现原图片。例如BMP格式的图片。

3.2 有损压缩

指在压缩文件大小的过程中,损失了一部分图片的信息,也即降低了图片的质量(即图片被压糊了),并且这种损失是不可逆的

常见的有损压缩手段是按照一定的算法将临近的像素点进行合并。压缩算法不会对图片所有的数据进行编码压缩,而是在压缩的时候,去除了人眼无法识别的图片细节。因此有损压缩可以在同等图片质量的情况下大幅降低图片的体积。例如jpg格式的图片使用的就是有损压缩。

3.3 无损压缩

在压缩图片的过程中,图片的质量没有任何损耗。我们任何时候都可以从无损压缩过的图片中恢复出原来的信息。

压缩算法对图片的所有的数据进行编码压缩,能在保证图片的质量的同时降低图片的体积。例如png、gif使用的就是无损压缩。常用的压缩图片网站:tinify.cn/

3.4 压缩插件

聊一聊web图片小知识

项目中可压缩的时机也比较多,本地开发时压缩、打包时压缩、上传OSS压缩、Nginx资源压缩等等,可根据自己需求选择适合自身业务需求的。

四、图片格式

4.1 JPEG

问题1:JPEG和JPG有没有区别?

早期的DOS、Windows 95系统时代的“8.3文件名命名原则”(文件名不能超过8个字符或4个汉字) ,而扩展名不能超过3个字符,中间用小数点“.”分隔。但JPEG是4个字符组成的,无奈只能把4个字符变成3个字符,因此“JPG”格式就诞生了。

问题2:为什么JPG占有率这么大?

JPEG文件对于绝大多数文件通常都很小。 它的压缩使用有损算法,通过牺牲人眼不太敏感的区域的质量来最小化大小。

JPEG的压缩并不是对于所有图像都很管用,对于具有锐利边缘和颜色比较少的图像,JPEG并不是非常管用。常见的例子就是包含文字的图片,另一个是徽标:

聊一聊web图片小知识

问题3:你知道JPG还分了两种格式吗?

一种是线性加载(Baseline JPEG),一种是渐进式加载(Progressive JPEG),两者之间的视觉差异是加载图像的方式。 随着数据的到达,线性加载从上到下加载图像。 渐进式加载以非常低的质量一次打印整个图像,并且随着数据的到达,图像得到了改善。 这里是展示差异的动画:

聊一聊web图片小知识聊一聊web图片小知识

渐进式图片一开始大小框架就定好,不会像基本式图片一样,由于尺寸未设定而造成回流——提高的渲染性能;渐进式图片也有不足,就是吃CPU吃内存。

4.2 GIF

GIF具有无损压缩和有损压缩的混合特性。像素表示形式是无损的,但是颜色深度限制为每个像素8位,采用的是Lempel-Zev-Welch(LZW)压缩算法,最高支持256种颜色。这意味着文件将包含较少的颜色,但文件体积更小。 这是24位PNG和8位GIF之间的色彩表示的比较。

聊一聊web图片小知识

聊一聊web图片小知识

mac预览打开会变成帧(一直下↓键,就可以动起来了)

聊一聊web图片小知识

4.3 PNG

问题1:PNG为什么可以透明?

聊一聊web图片小知识

PNG是一种非常流行的无损压缩格式,所有的浏览器都支持这种格式。 其设计目的是试图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。PNG使用从LZ77派生的无损数据压缩算法。PNG图片主要有三个类型,分别为 PNG 8/ PNG 24 / PNG 32。 位数越高,存储的颜色就越多(2^n),同时占用的体积也越大

聊一聊web图片小知识

APNG

APNG 全称是 Animated Portable Network Graphics , 是 PNG 格式的动画扩展,其简单说就是多张PNG合成的动图。可以看下下面两张对比图:

聊一聊web图片小知识

很明显,GIF边缘泛白的情况很突出,APNG就没有这样的问题。在线demo:PNG 对比 APNG 预览,感兴趣的也可以自己去做一个APNG图片:APNG在线合成下载工具。也可以看看这篇科普文科普(APNG) - B站一个有趣的解释

MNG

聊一聊web图片小知识

问题2:既然APNG相比GIF怎么完美,为什么没人用?

动态图虽然广受欢迎,互联网对其的需求也很大,但画质不是决定性因素。看有人这样说:即便是GIF这样糟糕的画质,人们也是乐此不彼的去欣赏一幅GIF中讲述的事情,所以画质不是动图的主要关注点

相关博文

4.4 WEBP

概念

WebP是由Google最初在2010年发布,目标是减少文件大小。它能同时支持无损压缩和有损压缩。它几乎集成了以上所有图片的优点,并且能够拥有更高的压缩率。

看一个统计(比较早的了):YouTube 的视频略缩图采用 WebP 格式后,网页加载速度提升了 10%;谷歌的 Chrome 网上应用商店采用 WebP 格式图片后,每天可以节省几 TB 的带宽,页面平均加载时间大约减少 1/3;Google+ 移动应用采用 WebP 图片格式后,每天节省了 50TB 数据存储空间。

聊一聊web图片小知识

转换

通过vue-webp-plugin和webp-loader 可以在打包阶段进行图片格式的转换,优化项目体积,提升用户体验。不过格式的转换一般用在CDN平台,在一个图片管理平台,生成不同场景下需要的不同格式。如果公司还没有,搭建一个这样的平台,又是一个可搞的小基建🤠

兼容性

都2022年了,兄弟们,放自己一马

聊一聊web图片小知识

4.4 SVG

SVG格式比较特殊,与其他格式有很大不同。 SVG图像存储的是几何形状,而不是每个像素的值。 它的主要优势是可以无限放大而不会造成质量损失,具体可以看下图的对比:

聊一聊web图片小知识

SVG文件类型主要用于徽标,但也用于几何形状的图像。 这种文件的主要缺点是:

对于徽标等小图片,文件大小通常比PNG或WebP大,尤其对于形状复杂,不规则的logo。在大多数情况下,无法将图片有效地转换为SVG(有一些工具说可以做到这一点,但效果并不理想)。

不论视图大小如何,SVG文件的图像质量都很高。 所有现代浏览器都支持它。

4.5 其他格式

其他的格式在图像质量和文件大小方面都更好(BPG, JPEG 2000, JPEG XR),但因为某些格式受专利保护,无法在网络上广泛使用。

聊一聊web图片小知识

五、img标签的应用

5.1 img属性

  • src 注意在vue和react中的路径问题
  • alt 在图片不能正常显示时出现的文本提示
  • title 在鼠标在移动到元素上的文本提示
  • width、height、border 提前设置好标签宽高,可以减少重绘次数,如果html标签都支持这种写法就舒服了
  • loading 懒加载,srcset 响应式,都是实验性属性,不大好用的感觉
  • onload、onerror

5.2 发起跨域请求

  • crossorigin
    • img的这个属性可以控制是否支持cors来获取图像资源,该属性支持两个值:anonymous 和 use-credentials
  • anonymous
    • 执行一个跨域请求获取资源,但不可以携带cookie、证书或者 HTTP 基本验证信息
  • use-credentials
    • 跨域请求获取资源,可以携带cookie、证书或者 HTTP 基本验证信息 利用这些属性,我们可以用img做一些环境嗅探相关技术方案(比如曝光埋点),只能发送get请求,拿不到响应,一般只需求在onload和onerror监听请求是否成功即可

5.3 相关css

background

相信大哥们都懂这个,就简单列举下属性

  • background-color
  • background-image
  • background-repeat
  • background-attachment
  • background-position
div {background:#ffffff url('img_tree.png') no-repeat right top;}

background-size

  • 设置背景图片拉伸效果
  • cover: 缩放背景图片以完全覆盖背景区,可能背景图片部分看不见
  • contain:缩放背景图片以完全填充背景区,可能背景区部分空白
  • 单个具体数值,eg:background-size: 50% 设置图片的宽度
  • 两个具体数值,eg:background-size: 50% auto 设置图片的宽高

聊一聊web图片小知识

object-fit

  • 指定元素的内容应该如何去适应指定容器的高度与宽度,对图片进行剪切,保留原始比例。挺有用的,学到就是赚到。
  • 和background-size区别,可用于img, video等的标签,background-size只能用于背景图
  • object-fit & object-position 在线体验demo

聊一聊web图片小知识

filter

  • css3的filter真的是无敌
  • 可以实现图片模糊、高亮、调色、阴影等各类效果,像手机中的各类滤镜都可以用用这个来搞一搞
  • CSS filter demo
img {
    filter: grayscale(1); // 黑白
    filterblur(4px); // 模糊
    filterbrightness(200%); // 高亮
    filtercontrast(200%); // 对比度
    filter: drop-shadow(8px 8px 10px red); // 阴影
    filterfilter: hue-rotate(90deg); // 色相旋转
    filterfilterinvert(100%); // 反转输入图像
    filterfilteropacity(30%); // 透明度
    filtersaturate(800%); // 饱和度
    filtercontrast(200%) brightness(150%);  // 使用多个滤镜,每个滤镜使用空格分隔
}

六、性能&体验优化

6.1 懒加载

监听可视区域

// 监听页面滚动 
// 在一开始加载的时候 
<img data-src="http://xx.com/xx.png" src="" /> 
// 在进入可视范围内时 
<img data-src="http://xx.com/xx.png" src="http://xx.com/xx.png" /> 
//可视区域的高度 
const viewHeight = window.innerHeight || document.documentElement.clientHeight; 
//元素距离可视区域顶部的高度 
let distance = viewHeight - imgs[i].getBoundingClientRect().top; 
// 可根据设置距离顶部多少时开始图片加载 
Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。 

img元素Loading 属性

<img src="image.jpg" alt="..." loading="lazy"> 
<iframe src="video-player.html" title="..." loading="lazy"></iframe> 

基于IntersectionObserver交叉API实现

Intersection Observer API 提供了一种异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。

聊一聊web图片小知识

懒加载基础实现

let images = document.querySelectorAll(".lazyload"); 
    let observer = new IntersectionObserver( 
      (entries) => { 
        entries.forEach((item) => { 
          if (item.isIntersecting) { 
            item.target.src = item.target.dataset.src; // 开始加载图片,把data-src的值放到src 
            observer.unobserve(item.target); // 停止监听已开始加载的图片 
          } 
        }); 
      }, 
      { 
        rootMargin: "0px 0px -100px 0px", // 交叉过视图的100,才开始派发事件 
      } 
    ); 
    images.forEach((item) => observer.observe(item)); 

6.2 高斯模糊

高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe PhotoshopGIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次。这种模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同。高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)。 从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作“高斯分布”,所以这项技术就叫作高斯模糊。

原理

  1. 渲染一个容器,保持与原图的比例和尺寸相同,填充一个较浅的背景色;
  2. 先加载小图,同时使用模糊效果;
  3. 小图加载完成,开始请求大图;
  4. 大图加载完成,显示大图,隐藏小图。

效果

点击预览 progressive image demo For Vanilla JS

聊一聊web图片小知识

6.3 小图片转base64

提升性能: 网页上的每一个图片,都是需要消耗一个 http 请求下载而来的, 图片的下载始终都要向服务器发出请求,要是图片的下载不用向服务器发出请求,base64 可以随着 HTML 的下载同时下载到本地,减少 https 请求。

// 将项目中小于 10kb 的图片转化为 base64 应用到页面中

module.exports = {
  ...
  module: {
  rules: [
      {
      test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
      loader: 'url-loader',
      options: {
      limit: 1024,
      name: utils.assetsPath('img/[name].[hash:7].[ext]'),
      }
    },
  ],
  },
}

6.4 响应式图片加载

在不同分辨率的设备上显示不同尺寸的图片,避免资源的浪费。常用的方法就是 css3 的媒体查询

@media screen and (min-width: 1200px) {
    img {
      background-image: url('1.png');
    }
}
@media screen and (min-width: 992px) {

}
@media screen and (min-width: 768px) {

}
@media screen and (min-width: 480px) {

}

还可以使用 HTML5 的 picture 标签进行响应式处理,现在也有一些呼声说可以用picture代替img,目前看picture除了不支持IE,其它支持的都挺好,有相关需求的兄弟们可以用起来了

<picture>
    <source srcset="src/img/l.png" media="(min-width: 1200px)" />
    <source srcset="src/img/2.png" media="(min-width: 992px)" />
    <source srcset="src/img/4.png" media="(min-width: 768px)" />
    <img src="src/img/4.png" />
</picture>

6.5 骨架屏

6.6 图片生成服务

有赞微商城包括了 PC 端、H5 端和小程序端,每个端都有绘制分享海报的需求。最早的时候是在每个端通过canvas API来绘制的,通过canvas绘制有很多痛点,于是乎就有了海报生成服务的出现,简单对比下两种实现:

聊一聊web图片小知识

海报服务流程图

聊一聊web图片小知识

服务优化

  • 优化Chromium启动项,启动一个最小化可用的浏览器实例,其他不需要的功能都禁用掉,这样会大大提升启动速度
  • 每次绘制采用新开标签页的行为,而不是新开一个实例
  • Chromium定时刷新机制
  • Redis缓存,避免重复绘制

6.7 其它优化点

  • 图片预加载:利用浏览器空闲时间,做后台请求图片资源,借助preload,prefetch提高图片加载层级,实现预加载
  • 使用css代替某些图片,比如实现修饰效果,如半透明、边框、圆角、阴影、渐变等,在当前主流浏览器中都可以用 CSS 达成,这样能减少图片的请求,达到优化的目的。
  • 使用iconfont
  • 升级Http2.0(长连接,多路复用,首部压缩,服务端推送等)
  • 等等

七、参考 & PPT

聊一聊web图片小知识

聊一聊web图片小知识

八、往期回顾

转载自:https://juejin.cn/post/7116715255404691493
评论
请登录