image-compressor
一个简单的JavaScript图像压缩器。使用浏览器的原生canvas.toBlob API做的压缩工作。一般使用此压缩是在客户端图像文件上传之前。
实例模板:Website
github:image-compressor
Getting started(新手入门)
Install(npm 安装)
npm install image-compressor.js // 注意是image-compressor.js 不是 image-compressor那是另一个包
Usage(使用)
Syntax语法
new ImageCompressor([file[, options]])
参数说明
file:(可选)压缩的目标图像文件,类型是 File 或者 Blob
options:(可选)压缩选项,类型是 Object
案例
<input type="file" id="file" accept="image/*">
import axios from 'axios'import ImageCompressor from 'image-compressor.js' // 引入document.getElementById('file').addEventListener('change', (e) => { const file = e.target.files[0]; // file对象 if (!file) { return } // 为空处理 new ImageCompressor(file, { quality: .6, success(result) { const formData = new FormData(); // FormData学习地址 https://developer.mozilla.org/zh-CN/docs/Web/API/FormData formData.append('file', result, result.name); // 通过XMLHttpRequest服务发送压缩的图像文件-Send the compressed image file to server with XMLHttpRequest. axios.post('/path/to/upload', formData).then(() => { console.log('Upload success'); }); }, error(e) { console.log(e.message); }, }); });
Options参数
checkOrientation
是否检查图片的 orientation 属性,类型是 boolean。默认值是 true。
提示:如果读取图像的EXIF的 orientation 属性(JPEG图像),有可能根据 orientation 属性自动翻转或旋转图像。
注意:不要一直相信这一点,因为一些JPEG图像有不正确的(不是标准的) orientation 属性
maxWidth
输出图像的最大宽度,类型是 number。默认值是 Infinity。值应该大于0。
因为一个canvas元素的大小限制,所以为了避免得到一个空白的输出图像,你可能需要给最大宽度和最大高度选项设置有限的数字。
maxHeight
输出图像的最大高度,类型是 number。默认值是 Infinity。值应该大于0。
minWidth
输出图像的最小宽度,类型是 number。默认值是 0。该值应大于0且不应大于maxWidth
minHeight
输出图像的最小宽度,类型是 number。默认值是 0。该值应大于0且不应大于maxHeight
width
输出图像的宽度,类型是 number。默认值是 undefined。值应该大于0。
如果没有指定,将使用原始图像的自然宽度,或者如果设置高度选项,则宽度将由自然长宽比自动计算。
height
输出图像的高度,类型是 number。默认值是 undefined。值应该大于0。
如果没有指定,将使用原始图像的自然高度,或者如果设置宽度选项,则高度将由自然长宽比自动计算。
注意:为了保持与原始图像相同的宽高比,如果设置宽度选项,将使用它自动计算高度,这意味着高度选项将被忽略。
quality
输出图像的画质,类型是 number。默认值是 undefined。值是0到1之间的数字。
小心使用1,因为它可能使输出图像的尺寸变大。
注意:此选项仅适用于 JPEG 和 WebP 格式的图像。
Examples:
值 | 图片原来大小 | 图片压缩大小 | 压缩比例 | 描述 |
---|---|---|---|---|
0 | 2.12MB | 114.61 KB | 94.72% | - |
0.2 | 2.12MB | 349.57 KB | 83.90% | - |
0.4 | 2.12MB | 517.10 KB | 76.18% | - |
0.6 | 2.12MB | 694.99 KB | 67.99% | 推荐 |
0.8 | 2.12MB | 1.14 MB | 46.41% | 推荐 |
1 | 2.12MB | 2.12 MB | 0% | 不推荐 |
NaN | 2.12MB | 2.01 MB | 5.02% | - |
mimeType
输出图像的文件类型,类型是 string。默认值是 auto。默认情况下,源映像文件的原始MIME类型将被使用。
convertSize
输出图像的文件类型,类型是 number。默认值是 5000000 (5MB)。
PNG文件超过此值将被转换为JPEG格式。若要禁用此功能,只需将值设置为无穷大。
Examples (in Chrome 61):
convertSize | 输入的文件大小Input size (type) | 输出的文件大小Output size (type) | 压缩比 |
---|---|---|---|
5 MB | 1.87 MB (PNG) | 1.87 MB (PNG) | 0% |
5 MB | 5.66 MB (PNG) | 450.24 KB (JPEG) | 92.23% |
5 MB | 9.74 MB (PNG) | 883.89 KB (JPEG) | 91.14% |
beforeDraw(context, canvas)
在将图像绘制到画布中进行压缩之前,要执行的钩子函数,类型是 Function。默认值是 null。
参数说明:
context: canvas的2D渲染上下文。
canvas: 压缩画布
new ImageCompressor(file, { beforeDraw(context) { context.fillStyle = '#fff'; }, });
drew(context, canvas)
该钩子函数执行后,将图像绘制到画布中进行压缩,类型是 Function。默认值是 null。
参数说明:
context: canvas的2D渲染上下文。
canvas: 压缩画布
new ImageCompressor(file, { drew(context) { context.filter = grayscale(100%); }, });
success(result)
成功压缩图像时执行的钩子函数,类型是 Function。默认值是 null。
参数说明:
result: 压缩后的图像(一个Blob对象)。
error(err)
当图像压缩失败时执行的钩子函数,类型是 Function。默认值是 null。
参数说明:
err: 压缩错误(一个Error对象)。
方法
compress(file[, options])
file:(必选)压缩的目标图像文件,类型是 File 或者 Blob
options:(可选)压缩选项,类型是 Object
返回值: Promise
使用:
const imageCompressor = new ImageCompressor(); imageCompressor.compress(e.target.files[0], { quality: 0.8, maxHeight: 1000, maxWidth: 1000}).then((result) => { // 压缩成功的回调 Handle the compressed image file. const formData = new FormData() formData.append('file', result) // 请求:Send the compressed image file to server with XMLHttpRequest... // var xhr = new XMLHttpRequest() // xhr.withCredentials = true...}).catch((err) => { // 压缩失败的回调 Handle the error console.log(err) })
浏览器支持
Chrome (latest)
Firefox (latest)
Safari (latest)
Opera (latest)
Edge (latest)
Internet Explorer 10+ (requires a Promise polyfill as es6-promise)
案例
基于vue的element-ui图片上传前的压缩,注意是element-ui的上传组件。
首先:
npm install image-compressor.js
然后:
import ImageCompressor from 'image-compressor.js' // 引入图片压缩
构写代码:
html
<el-upload :httpRequest="httpRequest"></el-upload>
httpRequest
httpRequest (options) { // 覆盖默认的上传行为,可以自定义上传的实现,解决压缩问题 if (this.imageCompress && this.acceptName === 'image/*') { // 如果允许压缩,并且当前上传的是图片 var imageCompressor = new ImageCompressor() // 压缩成功则使用压缩的结果,不成功直接上传 imageCompressor.compress(options.file, { quality: 0.8, maxHeight: 1000, maxWidth: 1000 }).then((result) => { // 压缩成功的回调 options.file = result console.log(options) return ajax(options) // 压缩成功把压缩成功的数据传递给ajax.js }).catch((err) => { // 压缩失败的回调 console.log(err) return options.file // 压缩失败把原文件传递 }) } else { return ajax(options) } }
ajax.js
使用说明:ajax.js可以拿出来单独使用哟!如果需要封装成引用型组件,请自行封装。
function getError (action, option, xhr) { let msg if (xhr.response) { msg = `${xhr.response.error || xhr.response}` } else if (xhr.responseText) { msg = `${xhr.responseText}` } else { msg = `fail to post ${action} ${xhr.status}` } const err = new Error(msg) err.status = xhr.status err.method = 'post' err.url = action return err }function getBody (xhr) { const text = xhr.responseText || xhr.response if (!text) { return text } try { return JSON.parse(text) } catch (e) { return text } }export default function upload (option) { if (typeof XMLHttpRequest === 'undefined') { return } const xhr = new XMLHttpRequest() const action = option.action if (xhr.upload) { xhr.upload.onprogress = function progress (e) { if (e.total > 0) { e.percent = e.loaded / e.total * 100 } option.onProgress(e) } } const formData = new FormData() if (option.data) { Object.keys(option.data).forEach(key => { formData.append(key, option.data[key]) }) } formData.append(option.filename, option.file) xhr.onerror = function error (e) { option.onError(e) } xhr.onload = function onload () { if (xhr.status < 200 || xhr.status >= 300) { return option.onError(getError(action, option, xhr)) } option.onSuccess(getBody(xhr)) } xhr.open('post', action, true) if (option.withCredentials && 'withCredentials' in xhr) { xhr.withCredentials = true } const headers = option.headers || {} for (let item in headers) { if (headers.hasOwnProperty(item) && headers[item] !== null) { xhr.setRequestHeader(item, headers[item]) } } xhr.send(formData) return xhr }
结语
到此我们学会了使用image-compressor.js进行图片压缩,并且可以根据image-compressor.js在图片上传前实现图片压缩。
作者:言墨儿
链接:https://www.jianshu.com/p/3ce3e3865ae2
热门评论
手机端的无法选择图片,你的也是嘛