切换至深色主题
图片(Image)实现技术
重要通知
类目简介
基本概况
不同终端设备加载
- ⚠️ 需要准备不同分辨率的图片数据源,否则同一张图片依旧是相同图片体积。
<picture>
<!-- 超大桌面屏:≥1680px -->
<source
srcset="{{ section.settings.image_1680 | img_url: '1680x' }}"
media="(min-width: 1680px)"
>
<!-- 笔记本/中端桌面屏:≥1366px -->
<source
srcset="{{ section.settings.image_1366 | img_url: '1366x' }}"
media="(min-width: 1366px)"
>
<!-- 平板横屏/小桌面:≥1025px(原代码断点) -->
<source
srcset="{{ section.settings.image | img_url: '1025x' }}"
media="(min-width: 1025px)"
>
<!-- 平板竖屏/大屏手机横屏:≥750px -->
<source
srcset="{{ section.settings.image_750 | img_url: '750x' }}"
media="(min-width: 750px)"
>
<!-- 兜底:手机竖屏(<750px),所有不匹配以上断点的设备 -->
<img
src="{{ section.settings.image_wap | img_url: '750x' }}"
width="100%"
height="auto"
alt="图片描述"
loading="lazy"
>
</picture>
<picture>
<source srcset="http://test.ysunlight.com/server/static/images/goods/001.jpg" media="(min-width: 1024px)" />
<img src="http://test.ysunlight.com/server/static/images/goods/002.jpg" />
</picture>
<picture>
<source srcset="landscape.png" media="(min-width: 1024px)" />
<img src="fallback.png" />
</picture>
<picture>
<source srcset="landscape.png" media="(min-width: 1000px)" width="1000" height="400" />
<source srcset="square.png" media="(min-width: 800px)" width="800" height="800" />
<source srcset="portrait.png" media="(min-width: 600px)" width="600" height="800" />
<img src="fallback.png" alt="当浏览器不支持来源时使用的图片" width="500" height="400" />
</picture>下载图片
export function downloadIamge(imgsrc, name) {
//下载图片地址和图片名
var image = new Image()
// 解决跨域 Canvas 污染问题
image.src = imgsrc
// image.src = imgsrc + '?timestamp=' + new Date().getTime()
// console.log(image)
image.setAttribute('crossorigin', 'anonymous')
image.onload = function () {
var canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
var context = canvas.getContext('2d')
context.drawImage(image, 0, 0, image.width, image.height)
var url = canvas.toDataURL('image/png') //得到图片的base64编码数据
var a = document.createElement('a') // 生成一个a元素
var event = new MouseEvent('click') // 创建一个单击事件
a.download = name || 'photo' // 设置图片名称
a.href = url // 将生成的URL设置为a.href属性
a.dispatchEvent(event) // 触发a的单击事件
}
image.onerror = (err) => {
console.log(err)
window.open(imgsrc)
// var img = document.getElementById('girlImg') // 获取要下载的图片
// var url = imgsrc // 获取图片地址
// var a = document.createElement('a') // 创建一个a节点插入的document
// var event = new MouseEvent('click') // 模拟鼠标click点击事件
// a.download = name // 设置a节点的download属性值
// a.href = url // 将图片的src赋值给a节点的href
// a.target = '_blank'
// a.dispatchEvent(event) // 触发鼠标点击事件
}
}图像<img>标签
定义 HTML 页面中的图像。
<!--draggable 设置拖动权限-->
<img src="" draggable="false" crossorigin="anonymous" alt="" title="" />
<!--crossorigin属性 | Access-Control-Allow-Credentials
anonymous:如果使用这个值的话就会在请求中的header中的带上Origin属性,但请求不会带上cookie和其他的一些认证信息。
use-credentials:这个就同时会在跨域请求中带上cookie和其他的一些认证信息。
例如阿里云OSS上的图片路径,设置crossorigin后需要加上时间戳,'jsdhfkhdjf?t=' + Date.now()
这里顺带提下img加载相关 属性
onload:表示加载好,换言之,没有加载好不会执行;
onAbort:图片加载的时候,用户通过点击停止加载时出发
onerror:如果图片不存在(网络很不通畅,也可能触发 onerror事件)
complete:图片显示出来以后为true,
-->srcset属性
是以逗号分隔的图像文件名及其宽度或密度描述符的列表。
- ⚠️ 需要准备不同分辨率的图片数据源,否则同一张图片依旧是相同图片体积。
<img
src="image-800.jpg"
srcset="
image-400.jpg 400w,
image-600.jpg 600w,
image-800.jpg 800w,
image-1000.jpg 1000w
"
sizes="(min-width: 1000px) 900px, calc(100vw - 2rem)"
alt="Product"
/>
<img
src="flower-large.jpg"
srcset="flower-small.jpg 480w, flower-large.jpg 1080w"
srcset="header640.png 640w, header960.png 960w, header1024.png 1024w"
sizes="50vw"
/>
<img
loading="lazy"
width="200"
height="200"
sizes="auto, (max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)"
srcset="
swing-200.jpg 200w,
swing-400.jpg 400w,
swing-800.jpg 800w,
swing-1600.jpg 1600w
"
src="swing-400.jpg"
alt="壶铃摆动" />
sizes 告诉浏览器:这张图在页面上占多宽
vw:视口单位,`100vw = 屏幕宽度
<!--模式 1:宽度描述符 w(最常用,配合 sizes)-->
语法:图片地址 宽度w, 图片地址 宽度w
w = 图片原生像素宽度,不是屏幕宽度
浏览器逻辑:
根据 sizes 算出图片实际显示宽度
自动对比 srcset 里图片宽度,选择满足分辨率最合适的图
src 作为降级兜底(不支持 srcset 的浏览器使用)
<!--模式 2:像素密度描述符 x(倍图,无需 sizes)-->
语法:图片地址 倍率x, 图片地址 倍率x
x = 设备像素比(1x 普通屏、2x 视网膜屏、3x 高清手机屏)
适合:图片固定尺寸展示(图标、固定 banner)
<!--
⚠️ # 和 x 描述符区分(不要搞混)
- `srcset 400w 800w + sizes`:**窗口宽度变化,切换不同体积图片(我们要的效果)**
- `srcset 1x 2x`:**只看设备屏幕 DPR,不看窗口大小,小窗口高 DPR 依旧加载大图**,不适合响应式窗口切换图片。
-->案例 1:w 宽度模式(响应式大图,配合 sizes,主流方案)
语法说明
srcset="url1 宽度w, url2 宽度w, url3 宽度w"
sizes="媒体条件 图片显示宽度, 默认宽度"
sizes 告诉浏览器:这张图在页面上占多宽
vw:视口单位,`100vw = 屏幕宽度
示例:窗口不同宽度,图片展示宽度不一样
<img
src="img-1080.jpg"
<!-- 多张图原生宽度 -->
srcset="img-480.jpg 480w, img-720.jpg 720w, img-1080.jpg 1080w, img-1440.jpg 1440w"
<!--
规则:
视口≥1200px → 图片显示宽度600px
视口≥768px → 图片显示宽度80vw
其余情况 → 图片显示宽度100vw
-->
sizes="(min-width: 1200px) 600px, (min-width:768px) 80vw, 100vw"
alt="花卉图片"
>
⚠️ 重要规则:使用 w 单位强烈建议搭配 sizes;不写 sizes,浏览器默认sizes=100vw,容易选错图片。案例 2:固定 50vw
图片始终占视口 50% 宽度
浏览器计算演示: 屏幕宽度 1000px → 图片显示宽度 = 500px 浏览器优先选择 ≥500px 宽度的图片 → 加载 flower-large.jpg(1080w)
<img
src="flower-large.jpg"
srcset="flower-small.jpg 480w, flower-large.jpg 1080w"
sizes="50vw"
alt="花朵"
/>案例 3:x 倍图模式(图标、固定尺寸图片,不需要 sizes)
适合固定大小图片,不用写 sizes
普通屏幕:加载 1x iphone / 安卓高清屏:自动加载 2x/3x 高清图
<img
src="icon-1x.png"
srcset="icon-1x.png 1x, icon-2x.png 2x, icon-3x.png 3x"
alt="图标"
width="48" height="48"
/>案例 4:混合禁用!❌ 禁止 w 和 x 混用
<!-- 错误!不能同时有w 和 x -->
<img srcset="a.jpg 480w, b.jpg 2x">案例 5:picture + srcset 艺术响应式(换图,不只是换尺寸)
srcset 只是同构图不同尺寸;想要不同屏幕展示完全不一样裁切图,搭配
<picture>
<picture>
<source media="(min-width:1000px)" srcset="banner-pc.jpg">
<source media="(min-width:600px)" srcset="banner-tablet.jpg">
<img src="banner-mobile.jpg" alt="轮播图">
</picture>案例 6:极简移动端自适应(只两张图)
<img
src="720.jpg"
srcset="480.jpg 480w, 720.jpg 720w"
sizes="100vw"
alt="海报"
/>sizes属性
表示资源大小的、以逗号隔开的一个或多个字符串。在支持 srcset 的用户代理中,当使用 w 描述符时,src 属性会被忽略。当匹配了媒体条件 (max-width: 600px) 时,将加载 200 像素宽的图像(最匹配的图像),否则将加载另一幅图像。
<img
src="clock-demo-200px.png"
alt="Clock"
srcset="clock-demo-200px.png 200w, clock-demo-400px.png 400w"
sizes="(max-width: 600px) 200px, 50vw" />
<img
loading="lazy"
width="200"
height="200"
sizes="auto, (max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)"
srcset="
swing-200.jpg 200w,
swing-400.jpg 400w,
swing-800.jpg 800w,
swing-1600.jpg 1600w
"
src="swing-400.jpg"
alt="壶铃摆动" />
<!--窗口不同宽度,图片展示宽度不一样-->
<img
src="img-1080.jpg"
<!-- 多张图原生宽度 -->
srcset="img-480.jpg 480w, img-720.jpg 720w, img-1080.jpg 1080w, img-1440.jpg 1440w"
<!--
规则:
视口≥1200px → 图片显示宽度600px
视口≥768px → 图片显示宽度80vw
其余情况 → 图片显示宽度100vw
-->
sizes="(min-width: 1200px) 600px, (min-width:768px) 80vw, 100vw"
alt="花卉图片"
>loading 属性
loading 属性指定浏览器是应立即加载图像还是延迟加载图像。
----------------------------------------------------------------------------------
值 描述
----------------------------------------------------------------------------------
eager 默认,图像立即加载。
lazy 图像延迟加载,只有鼠标滚动到该图片所在位置才会显示。
----------------------------------------------------------------------------------- 代码示例
<!--loading属性支持的值
auto: 浏览器默认的延迟加载行为,与不包含属性相同。
lazy:推迟资源的加载,直到它到达与视口的计算距离。
eager:立即加载资源,无论它位于页面上的哪个位置。
-->
<img src="image.png" loading="lazy" alt="…" width="200" height="200">
<!-- 设置延迟加载的图片 -->
<img decoding="async" src="/images/paris.jpeg" alt="Paris" style="width:100%" loading="lazy">decoding
用于告诉浏览器如何解析图像数据。具体来说,在渲染其他的内容更新前,是否应该等待图像解码完成。
表示解码方式的字符串。可选的值有:
"sync"
同步解码图像,与其他内容一起原子化渲染。
"async"
异步解码图像,允许在解码完成前渲染其他内容。
"auto"
对解码模式没有偏好;让浏览器决定最适合用户的模式。这是默认值,但不同的浏览器拥有不同的默认行为:
Chromium 默认为 "sync"。
Firefox 默认为 "async"。
Safari 除少数情况外默认为 "sync"。fetchpriority
提供获取图像时要使用的相对的优先级提示。
<img
src="image.png"
fetchpriority="high" 表示其获取优先级相对其他图像要高。
fetchpriority="low" 表示其获取优先级相对其他图像要低。
fetchpriority="auto" 默认值:表示自动确定其相对其他图像的获取优先级。
/>相关操作方法
// 获取图片路径
let URL = window.URL || window.webkitURL;
let img_src = URL.createObjectURL(url);
// 释放内存
URL.revokeObjectURL(img_src);
const image = new Image();
image.onload = function(e) {
let width = image.naturalWidth;
let height = image.naturalHeight;
if (width > height) {
setw = window.FONT['size']/100*225;
seth = window.FONT['size']/100*169;
} else {
setw = window.FONT['size']/100*169;
seth = window.FONT['size']/100*225;
}
document.body.append(image);
}
image.onerror = function() {
//
}
image.crossOrigin = 'anonymous';
image.src = thumbnail;
const initImageSize = (imageUrl: string) => {
const image = new Image()
return new Promise((resolve) => {
image.onload = function (e) {
const width = image.naturalWidth
const height = image.naturalHeight
resolve({ width, height })
}
image.onerror = function () {
resolve({})
}
image.crossOrigin = 'anonymous'
image.src = imageUrl
})
}上传图片
const fileEl: HTMLInputElement = document.createElement("input");
if (!fileEl) return;
fileEl.setAttribute("type", "file");
fileEl.setAttribute("accept", "image/gif,image/jpeg,image/png");
fileEl.click();
const getFileData = (fileTarget: HTMLInputElement) => {
return new Promise((resolve) => {
fileTarget.onchange = async function (e) {
// @ts-ignore # 忽视本行代码的小错误
resolve(e.target.files[0]);
};
});
};
const fileData = await getFileData(fileEl);
const formData = new FormData();
// @ts-ignore # 忽视本行代码的小错误
formData.append("file", fileData);new Image对象
上传图片本地预览
const fileEl: HTMLInputElement = document.createElement("input");
if (!fileEl) return;
fileEl.setAttribute("type", "file");
fileEl.setAttribute("accept", "image/gif,image/jpeg,image/png");
fileEl.click();
const getFileData = (fileTarget: HTMLInputElement) => {
return new Promise((resolve) => {
fileTarget.onchange = async function (e) {
// @ts-ignore # 忽视本行代码的小错误
resolve(e.target.files[0]);
};
});
};
const fileData = await getFileData(fileEl);
const reader = new FileReader();
// 异步
const getData = () => {
const reader = new FileReader();
return new Promise((resolve) => {
reader.onload = function(e) {
console.info(e.atrget.result);
resolve(reader.result);
}
});
}
const imagePath = await getData();
图片实现原理
图像(Image)
图像是位图(Bitmap)
图像增强
前端图像处理图图像增强
改善图像质量、分析图像、图像转换、图像处理
AlloyImage 图像处理库:https://tool.oschina.net/alloyphoto#http://alloyteam.github.io/AlloyPhoto/ 1.图层功能,提供图层的添加,删除,交换图层顺序等功能,且包含与PS相对应的17种图层混合模式 2.图像的基本调节功能,包括亮度、对比度,色相、饱和度、明度调节 3.多种滤镜功能,去色、反相、高斯模糊、锐化、浮雕效果、查找边缘、马赛克、腐蚀等 4.处理后文件的保存,处理完成之后,可以将文件输出为base64形式间接使用和保存 5.高级组合效果,如素描,lomo,复古,素描等复合效果 如一个素描效果的实现
图像滤镜艺术:专业介绍图像处理中各种滤镜的算法实现。
https://www.kancloud.cn/trent/hotoimagefilter/102786 图像滤镜实现万能方法研究:https://trent.blog.csdn.net/article/details/42212459?spm=1001.2101.3001.6650.17&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-18.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-18.no_search_link 图像处理的滤镜算法:https://blog.csdn.net/tomy2426214836/article/details/88889298 数字图像处理课题研究:https://blog.csdn.net/trent1985/category_9263763.html 数字图像处理研究:https://blog.csdn.net/trent1985/category_1850555.html 图片滤镜算法原理简单讲解:https://blog.csdn.net/weixin_34152820/article/details/85461116?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-1.no_search_link 图像处理的滤镜算法:https://blog.csdn.net/tomy2426214836/article/details/88889298 图像特效及滤镜算法汇总 https://blog.csdn.net/matrix_space/article/details/42743613?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-1.essearch_pc_relevant&spm=1001.2101.3001.4242.2
MIME-type
image/gif gif
image/jpeg jpe
image/jpeg jpeg
image/jpeg jpg
image/png png
image/bmp bmp
image/cis-cod cod
image/ief ief
image/pipeg jfif
image/svg+xml svg
image/tiff tif
image/tiff tiff
image/x-cmu-raster ras
image/x-cmx cmx
image/x-icon ico
image/x-portable-anymap pnm
image/x-portable-bitmap pbm
image/x-portable-graymap pgm
image/x-portable-pixmap ppm
image/x-rgb rgb
image/x-xbitmap xbm
image/x-xpixmap xpm
image/x-xwindowdump xwd常见不同图片格式
- APNG(动态可移植网络图形)——无损动画序列的不错选择(GIF 性能较差)。
- AVIF(AV1 图像文件格式)——静态图像或动画的不错选择,其性能较好。
- GIF(图像互换格式)——简单图像和动画的不错选择。
- JPEG(联合图像专家组)——有损压缩静态图像的不错选择(目前最流行的格式)。
- PNG(便携式网络图形)——对于无损压缩静态图像而言是不错的选择(质量略好于 JPEG)。
- SVG(可缩放矢量图形)——矢量图像格式。用于必须以不同尺寸准确描绘的图像。
- WebP(网络图片格式)——图像和动画的绝佳选择。
APNG
(动态可移植网络图形)——无损动画序列的不错选择(GIF 性能较差)。
AVIF
(AV1 图像文件格式)——静态图像或动画的不错选择,其性能较好。
GIF
(图像互换格式)——简单图像和动画的不错选择。
JPEG
(联合图像专家组)——有损压缩静态图像的不错选择(目前最流行的格式)。
PNG
(便携式网络图形)——对于无损压缩静态图像而言是不错的选择(质量略好于 JPEG)。
SVG
(可缩放矢量图形)——矢量图像格式。用于必须以不同尺寸准确描绘的图像。
WebP
(网络图片格式)——图像和动画的绝佳选择。
WebP
- 检测浏览器是否支持WebP格式图片
window.isSupportWebp = false; // 是否支持
(function() {
var img = new Image();
function getResult(event) {
// 如果进入加载且图片宽度为1(通过图片宽度值判断图片是否可以显示)
window.isSupportWebp = event && event.type === 'load' ? img.width == 1 : false;
}
img.onerror = getResult;
img.onload = getResult;
img.src = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA='; // 一像素图片
})();Gif
常见算法列表
FXAA 抗锯齿算法
FXAA 抗锯齿算法的实现:https://jelly.jd.com/article/5efd42154b54be014cf4e646
插件体系
cropperjs插件
官网:https://github.com/fengyuanchen/cropperjs vue-cropperjs:https://github.com/Agontuk/vue-cropperjs
vue-cropperjs裁剪的尺寸变化事件导致滚动失效
图片工具
CanvasKeyFrames
图片序列帧播放工具,用canvas操作图片动画,封装了常用方法。