Recently there have been major changes to the image library, adding a number of new methods. One of the most important features is the ability to compress images by specifying the size.


Two days ago, the company had a demand to compress large pictures and then upload them to the remote server. I found many methods on the Internet, but none of them worked well. Today, I wrote a method by myself and put it on my Githubhere

First, what is the demand?

First of all, what are our needs? Most of the time we need to compress a File object and pass it to the remote image server as a File object. Sometimes we also need to compress a Base64 string and pass it to a remote database as a Base64 string; Sometimes it might be a canvas, or it might be an Image object, or it might just be the URL of an Image, and we need to compress it and upload it remotely; Faced with so many demands, Wang er simply drew a picture:

Second, solutions

As shown in the figure above, Wang er wrote a total of seven methods, basically covering the conversion and compression of most file types in JS, among which:

1. UrltoImage (URL,fn) will load the required Image object through a URL, where the URL parameter is passed to the Image URL,fn is the callback method, containing an Image object parameter, the code is as follows:

function urltoImage (url,fn){
    var img = new Image();
    img.src = url;
    img.onload = function(){ fn(img); }};Copy the code

2. ImagetoCanvas (image) converts an image object to a Canvas object. The image argument is passed to an image object as follows:

function imagetoCanvas(image){
    var cvs = document.createElement("canvas");
    var ctx = cvs.getContext('2d');
    cvs.width = image.width;
    cvs.height = image.height;
    ctx.drawImage(image, 0.0, cvs.width, cvs.height);
    return cvs ;
};
Copy the code

3. CanvasResizetoFile (Canvas, Quality, FN) will compress a Canvas object into a Blob type object; The canvas argument is passed to a Canvas object; The quality parameter is passed in a 0-1 number type to indicate the image compression quality. Fn is the callback method and contains a Blob object parameter; The code is as follows:

function canvasResizetoFile(canvas,quality,fn){
    canvas.toBlob(function(blob) {
        fn(blob);
    },'image/jpeg',quality);
};
Copy the code

Blob objects here represent immutable, file-like raw data. Blobs represent data that is not necessarily native to JavaScript. The File interface is based on Blob, inheriting the functionality of Blob and extending it to support files on the user’s system. We can treat it as a File type, but refer to the MDN documentation for more specific uses

4. CanvasResizetoDataURL (Canvas, Quality) will compress a Canvas object into a dataURL string, in which canvas parameter is passed to a Canvas object; The quality parameter is passed in a 0-1 number type to indicate the image compression quality. The code is as follows:

methods.canvasResizetoDataURL = function(canvas,quality){
    return canvas.toDataURL('image/jpeg',quality);
};
Copy the code

The toDataURL API can be referenced in the MDN documentation

5. FiletoDataURL (file,fn) converts a file of type File (Blob) to a dataURL string, where file is passed to a file of type file (Blob); Fn is the callback method and contains a dataURL string parameter; The code is as follows:

function filetoDataURL(file,fn){
    var reader = new FileReader();
    reader.onloadend = function(e){
        fn(e.target.result);
    };
    reader.readAsDataURL(file);
};
Copy the code

DataURLtoImage (dataURL,fn) converts a string of dataURL strings toImage files, where dataURL parameter is passed to a dataURL string,fn is the callback method, containing an Image file parameter, code as follows:

function dataURLtoImage(dataurl,fn){
    var img = new Image();
    img.onload = function() {
        fn(img);
    };
    img.src = dataurl;
};
Copy the code

DataURLtoFile (dataURL) converts a string of dataURL strings to Blob objects, where the dataURL argument is passed a dataURL string as follows:

function dataURLtoFile(dataurl) {
    var arr = dataurl.split(', '), mime = arr[0].match(/ : (. *?) ; /) [1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
};
Copy the code

Third, further encapsulation

For the common compression of a File object into a File object, we can encapsulate the above method, refer to the following code:

function fileResizetoFile(file,quality,fn){
    filetoDataURL (file,function(dataurl){
        dataURLtoImage(dataurl,function(image){ canvasResizetoFile(imagetoCanvas(image),quality,fn); })})}Copy the code

The file argument is passed in a file (Blob) file; The quality parameter is passed in a 0-1 number type to indicate the image compression quality. Fn is the callback method and contains arguments to a Blob file.

It works like this:

var file = document.getElementById('demo').files[0];
fileResizetoFile(file,0.6.function(res){
    console.log(res);
    // Get the res and do the operation you want to upload;
})
Copy the code

In this way, the image compression upload can be easily done. I have encapsulated the above 8 methods and put them on Github. If you like, you can try hard star ha.

Reference: MDN