Reprinted from
Author: Yan Mo'er
Link: https://www.jianshu.com/p/3ce3e3865ae2
Author: UYOU
Link: https://www.imooc.com/article/40038
Source: muke.com
image-compressor
A simple JavaScript image compressor. Use the browser's native canvas Compression work done by toblob API. This compression is generally used before the client image file is uploaded.
Instance template: Website
github: image-compressor
Getting started
Install(npm installation)
npm install image-compressor.js //Note that it is image compressor JS is not an image compressor. That's another package
Usage
Syntax syntax
new ImageCompressor([file[, options]])
Parameter description
File: (optional) compressed target image file, type: File Or Blob
options: (optional) compression option. The type is Object
case
<input type="file" id="file" accept="image/*">
import axios from 'axios'import ImageCompressor from 'image-compressor.js' //Import document getElementById('file'). Addeventlistener ('change ', (e) = > {const} file = e.target.files[0]; / / file object if (!file) { return } //Null processing new ImageCompressor(file, { quality: .6, success(result) { const formData = new FormData(); //Formdata learning address https://developer.mozilla.org/zh-CN/docs/Web/API/FormData formData.append('file', result, result.name); //Send the compressed image file through XMLHttpRequest Service - 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 parameter
checkOrientation
Whether to check the orientation attribute of the picture. The type is boolean. The default value is true.
Tip: if you read the orientation attribute (JPEG image) of the EXIF of the image, it is possible to automatically flip or rotate the image according to the orientation attribute.
Note: don't always believe this because some JPEG images have incorrect (not standard) orientation attributes
maxWidth
The maximum width of the output image. The type is number. The default is Infinity. Value should be greater than 0.
Because of the size limit of a canvas element, in order to avoid getting a blank output image, you may need to set limited numbers for the maximum width and maximum height options.
maxHeight
The maximum height of the output image. The type is number. The default is Infinity. Value should be greater than 0.
minWidth
The minimum width of the output image. The type is number. The default value is 0. The value should be greater than 0 and should not be greater than maxWidth
minHeight
The minimum width of the output image. The type is number. The default value is 0. The value should be greater than 0 and not greater than maxHeight
width
The width of the output image. The type is number. The default value is undefined. Value should be greater than 0.
If not specified, the natural width of the original image will be used, or if the height option is set, the width will be calculated automatically by the natural aspect ratio.
height
The height of the output image. The type is number. The default value is undefined. Value should be greater than 0.
If not specified, the natural height of the original image will be used, or if the width option is set, the height will be calculated automatically by the natural aspect ratio.
Note: in order to maintain the same aspect ratio as the original image, if you set the width option, it will be used to automatically calculate the height, which means that the height option will be ignored.
quality
The image quality of the output image. The type is number. The default value is undefined. The value is a number between 0 and 1.
Use 1 carefully as it may make the size of the output image larger.
Note: this option only applies to images in JPEG and WebP formats.
Examples:
value | Original size of picture | Picture compression size | Compression ratio | describe |
---|---|---|---|---|
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% | recommend |
0.8 | 2.12MB | 1.14 MB | 46.41% | recommend |
1 | 2.12MB | 2.12 MB | 0% | Not recommended |
NaN | 2.12MB | 2.01 MB | 5.02% | - |
mimeType
The file type of the output image is string. The default is auto. By default, the original MIME type of the source image file will be used.
convertSize
The file type of the output image is number. The default value is 5000000 (5MB).
PNG files exceeding this value will be converted to JPEG format. To disable this feature, simply set the value to infinity.
Examples (in Chrome 61):
convertSize | Input size (type) | Output size (type) | Compression ratio |
---|---|---|---|
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)
The hook Function to be executed before drawing the image into the canvas for compression. The type is Function. The default value is null.
Parameter Description:
Context: 2D rendering context of canvas.
Canvas: compress canvas
new ImageCompressor(file, { beforeDraw(context) { context.fillStyle = '#fff'; }, });
drew(context, canvas)
After the hook Function is executed, the image is drawn into the canvas for compression. The type is Function. The default value is null.
Parameter Description:
Context: 2D rendering context of canvas.
Canvas: compress canvas
new ImageCompressor(file, { drew(context) { context.filter = grayscale(100%); }, });
success(result)
The hook Function executed when the image is compressed successfully. The type is Function. The default value is null.
Parameter Description:
result: compressed image (a Blob object).
error(err)
The hook Function executed when image compression fails. The type is Function. The default value is null.
Parameter Description:
err: compression Error (an Error object).
method
compress(file[, options])
File: (required) compressed target image file, type: File Or Blob
options: (optional) compression option. The type is Object
Return value: Promise
use:
const imageCompressor = new ImageCompressor(); imageCompressor.compress(e.target.files[0], { quality: 0.8, maxHeight: 1000, maxWidth: 1000}).then((result) => { //Callback , Handle , the , compressed , image , file const formData = new FormData() formData.append('file', result) //Request: Send the compressed image file to server with XMLHttpRequest // var xhr = new XMLHttpRequest() // xhr.withCredentials = true...}).catch((err) = > {/ / callback for compression failure console.log(err) })
Browser support
-
Chrome (latest)
-
Firefox (latest)
-
Safari (latest)
-
Opera (latest)
-
Edge (latest)
-
Internet Explorer 10+ (requires a Promise polyfill as es6-promise)
case
vue based element UI image compression before uploading. Note that it is the upload component of element UI.
first:
npm install image-compressor.js
then:
import ImageCompressor from 'image-compressor.js' //Introduce picture compression
Construction Code:
html
<el-upload :httpRequest="httpRequest"></el-upload>
httpRequest
httpRequest (options) { //Override the default upload behavior. You can customize the upload implementation to solve the compression problem if (this.imageCompress && this.acceptName === 'image/*') { //If compression is allowed and the image is currently uploaded var imageCompressor = new ImageCompressor() //If the compression is successful, the compression result will be used. If not, it will be uploaded directly imageCompressor.compress(options.file, { quality: 0.8, maxHeight: 1000, maxWidth: 1000 }).then((result) => { //Callback for compression success options.file = result console.log(options) return ajax(options) //The compressed data is passed to Ajax js }).catch((err) => { //Callback for compression failure console.log(err) return options.file //Compression failed to transfer the original file }) } else { return ajax(options) } }
ajax.js
Instructions: Ajax JS can be used alone! If you need to package it as a reference component, please package it yourself.
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 }
epilogue
At this point, we have learned to use image compressor JS for image compression, and can be based on image compressor JS realizes image compression before image upload.