阿里云 OSS
通过文件访问 URL 处理图片
您可以在图片的访问 URL 后添加相应的图片处理参数或图片样式处理图片,格式如下: 使用图片处理参数
- 格式为:https://bucketname.endpoint/objectname?x-oss-process=image/action,parame_value
- https://bucketname.endpoint/objectname:Object的访问地址,获取方式请参见上传Object后如何获取访问URL。
- x-oss-process=image/:固定参数,标明使用图片处理参数对图片文件进行处理。
- action,parame_value:图片处理的操作(action)、参数(parame)和值(value),用于定于图片处理的方式。多个操作以正斜线(/)隔开,OSS 将按图片处理参数的顺序处理图片。例如 image/resize,w_200/rotate,90 表示将图片先按比例缩放至宽 200 px,再将图片旋转 90°。图片处理支持的参数请参见处理参数。
- 示例:http://image-demo.oss-cn-hangzhou.aliyuncs.com/example.jpg?x-oss-process=image/resize,w_300/quality,q_90
使用样式参数
- 格式为:https://bucketname.endpoint/objectname?x-oss-process=style/stylename https://bucketname.endpoint/objectname:Object的访问地址。
- x-oss-process=style/:固定参数,标明使用图片样式参数对图片文件进行处理。
- stylename:您提前在 OSS 控制台设置的样式名称,配置方法请参见 t4792.html#section_qu7_jfq_ckj。
示例:http://image-demo.oss-cn-hangzhou.aliyuncs.com/examplejpg?x-oss-process=style/panda_style
若您设置了自定义分隔符,可使用分隔符代替?x-oss-process=style/内容,进一步简化图片处理 URL。例如分隔符设置为感叹号(!),则图片处理 URL 为:<https://bucketname.endpoint/objectname!stylename。自定义分隔符的配置方式请参见设置自定义分隔符。
参数
图片处理 | 参数 | 说明 |
---|---|---|
图片高级压缩 | format | 将图片转换为 HEIF 或 WebP M6 等高压缩比格式。 |
图片缩放 | resize | 将图片缩放至指定大小。 |
内切圆 | circle | 以图片中心点为圆心,裁剪出指定大小的圆形图片。 |
自定义裁剪 | crop | 裁剪指定大小的矩形图片。 |
索引切割 | indexcrop | 按指定 x 或 y 轴的大小切分图片,之后取其中一张图片。 |
圆角矩形 | rounded-corners | 按指定圆角大小将图片裁剪成圆角矩形。 |
自适应方向 | auto-orient | 将携带旋转参数的图片进行自适应旋转。 |
旋转 | rotate | 按指定角度以顺时针方向旋转图片。 |
模糊效果 | blur | 对图片进行模糊处理。 |
亮度 | bright | 调整图片亮度。 |
锐化 | sharpen | 对图片进行锐化处理。 |
对比度 | contrast | 调整图片对比度。 |
渐进显示 | interlace | 将 JPG 格式的图片调整为渐进显示。 |
质量变换 | quality | 调整 JPG 和 WebP 格式图片的质量。 |
格式转换 | format | 转换图片格式。 |
图片水印 | watermark | 为图片添加图片或文字水印。 |
获取图片主色调 | average-hue | 获取图片主色调。 |
获取信息 | info | 获取图片信息,包括基本信息、EXIF 信息。 |
$process
import Vue from 'vue'
/**
* 浏览器是否支持webp
* @type {boolean}
*/
let webpSupported = false
const ResizeImage = {
/**
* 注册图片处理的全局方法 $process
* @param {object} _Vue vue
*/
install(_Vue) {
/**
* 为图片url添加缩放、格式转换等请求参数
* https://help.aliyun.com/document_detail/44686.html?spm=a2c4g.11186623.6.1235.61a5c1f60U7rVj
* @param {string} url 图片链接
* @param {object} params 参数
* @param {string} [params.style] 预定义参数
* @param {number} [params.width] 等比例缩放宽度
* @param {boolean} [params.matchScreen=false] 默认false,图片宽度匹配屏幕分辨率,但最大不会超过1980
* @param {boolean} [params.webp=true] 图片转换为webp,默认true
* @return {string} 处理后的图片链接
*/
_Vue.prototype.$process = (url, params = {}) => {
if (!url) {
return url
}
// 判断图片格式是否支持,不支持则返回原链接,不进行处理
if (!_support(url)) {
return url
}
if (url.indexOf('forucdn.com') === -1) {
return url
}
url = _modifyUrl(url)
const cmd = [
url,
// 默认增加渐进显示图片设置(interlace,1),由oss 自己判断是否渐进显示图片
// 渐进显示图片,只对jpg格式有效
(_getQuery(url) ? '&' : '?') + 'x-oss-process=image/interlace,1'
]
// 预定义尺寸
if (params.style) {
cmd.push(params.style)
}
// 图片宽度匹配屏幕分辨率,但最大不会超过1980
if (params.matchScreen) {
const width = Math.min(screen.width, 1980)
cmd.push(`/resize,w_${width}`)
}
// 等比例缩放
if (params.width) {
cmd.push(`/resize,w_${params.width}`)
}
// 转换为webp格式,默认不使用
params.webp = params.webp === undefined ? false : params.webp
// 由于效果图提升了图片质量,图片大小增加,使用webp图片格式来减小图片大小
// assets.forucdn.com 图片也使用webp
if (webpSupported && (params.webp || url.indexOf('samples.forucdn.com') !== -1 || url.indexOf('assets.forucdn.com') !== -1)) {
cmd.push('/format,webp')
}
// 当浏览器不支持webp图片时图片使用jpeg格式
if (!webpSupported) {
cmd.push('/format,jpg')
}
return cmd.join('')
}
}
}
/**
* 获取图片参数
* @param {string} url 图片链接
* @return {string} 图片后缀
*/
const _getQuery = (url) => {
if (url.indexOf('?') === -1) return ''
return url.slice(url.indexOf('?'))
}
/**
* 判断是否支持该图片类型
* @param {string} url 图片链接
* @return {boolean} 是否支持
*/
const _support = (url) => {
const reg = /\.(jpg|jpeg|png|bmp|gif|webp|tif|tiff)$/
return reg.test(url.replace(_getQuery(url), ''))
}
/**
* 如果图片类型为原图,需要修改为缩略图的链接
* @param {string} url 图片链接
* @returns {string} 修改后的图片链接
* @private
*/
const _modifyUrl = (url) => {
// 移除预定义样式
// @todo 待后台不再传该值时可以移除
url = url.replace(/\!index_slider|\!index_artists_avatar|\!index_collections/, '')
if (!url.match('galleries')) {
return url
}
const char_index = url.lastIndexOf('.')
return url.slice(0, char_index) + '-thumb' + url.slice(char_index)
}
/**
* 检测客户端是否支持webp
* @returns {boolean} 是否支持
*/
const _clientSideDetectionForWebp = () => {
return new Promise((resolve) => {
const image = new Image()
image.onerror = () => resolve(false)
image.onload = () => resolve(true)
image.src = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA='
// // If the browser doesn't has the method createImageBitmap, you can't display webp format
// if(!window.createImageBitmap){
// return resolve(false)
// }
// // Base64 representation of a white point image
// const webpdata = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoCAAEAAQAcJaQAA3AA/v3AgAA='
// // Retrieve the Image in Blob Format
// fetch(webpdata).then((response) => response.blob())
// .then((blob) => {
// // If the createImageBitmap method succeeds, return true, otherwise false
// window.createImageBitmap(blob).then(() => resolve(true), () => resolve(false))
// })
})
}
/**
* 服务端检测是否支持webp
* @param {object} ctx nuxt ctx
* @returns {boolean} 是否支持
* @private
*/
const _serverSideDetectionForWebp = (ctx) => {
const headers = ctx.req.headers
return _detectByAccept(headers.accept) || _detectByUserAgent(headers['user-agent'])
}
/**
* 通过headers头中的accept字段判断是否支持webp
* @param {string|undefined} accept accept字段值
* @returns {boolean} 结果
* @private
*/
const _detectByAccept = (accept) => {
return accept && null !== accept.match('image/webp')
}
/**
* 通过headers头中的user-agent字段判断是否支持webp
* @param {string|undefined} user_agent user-agent字段值
* @returns {boolean} 结果
* @private
*/
const _detectByUserAgent = (user_agent) => {
return user_agent && null !== user_agent.match(/Opera|Chrome|Firefox/)
}
export default async () => {
webpSupported = process.server ? false : await _clientSideDetectionForWebp()
Vue.use(ResizeImage)
}