Last week to do a mobile side of the image compression upload function. During the period of several pits, in this summary.
The general idea is that some API compatibility please refer to Caniuse:
Use FileReader to read a Blob object, or a file object, to convert a picture into the form of a data URI.
Using canvas, create a new canvas on the page and use the API provided by canvas to draw the picture into the canvas.
Using Canvas.todataurl () to compress the image and get the value of the data URI of the picture
Upload files.
Step 1, in the picture compression before, or the size of the picture to make a judgment, if the picture size is larger than 200KB, is a direct picture upload, do not compress the picture, if the size of the picture is greater than 200KB, it is the first image compression and then upload:
The code is as follows |
Copy Code |
<input type= "File" id= "choose" accept= "image/*" > var filechooser = document.getElementById ("Choose"), maxSize = 200 * 1024; 200KB Filechoose.change = function () { var file = This.files[0],//Read file reader = new FileReader ();
Reader.onload = function () { var result = This.result,//result as the form of the data URL img = new Image (), IMG.SRC = result;
if (Result.length < maxSize) { Imgupload (result); Picture upload directly } else { var data = Compress (IMG); The picture is first compressed Imgupload (data); Picture upload } }
Reader.readasdataurl (file); } |
Step 2, 3:
The code is as follows |
Copy Code |
var canvas = document.createelement (' canvas '), CTX = Canvas.getcontext (' 2d '); function Compress (img) { canvas.width = img.width; canvas.height = img.height; //drawing with canvas //Compress the original picture to 0.2 times times its original quality. var data = Canvas.todataurl (' image/jpeg ', 0.2);//data URL form return data; } |
In the process of drawing with canvas, there are problems with the uploading of iOS images:
When you get your phone up, take a picture, upload an image, and the picture will rotate automatically, and the problem will not occur when you take photos and upload pictures sideways. This time if you want to correct the picture automatic rotation, the picture into binary data (using the Binaryajax.js), easy to get the image of EXIF information, by obtaining EXIF information to determine the angle of the picture rotation (using the exif.js), And then the corresponding rotation of the image processing. How to fix it please poke me
In iOS, when the size of the picture is larger than 2MB, there will be a picture flattening, this time you need to reset the proportions of the picture. How to fix it please poke me
The use of FileReader, the process of reading the picture will take a certain amount of time, the picture data injected into the canvas canvas requires a certain amount of time, picture compression process, the larger the picture, the CPU calculation consumes the longer the time, may appear card situation. In short, this is a process that takes a while.
Step 4, there are 2 ways to upload files:
Convert a picture to a base64
Convert picture data to blob objects, upload files using formdata
Mode 1 can be submitted via XHR Ajax or XHR2 formdata.
Method 2 There's a big hole in here. Specific description please poke me
The simple point is that a BLOB object cannot be injected into a Formdata object.
When you get the data URI of the picture, convert it to a BLOB data type
The code is as follows |
Copy Code |
var ndata = Compress (IMG); Ndata = Window.atob (ndata); Decoding the data in the base64 format
Creates a new buffer object to store picture data var buffer = new Uint8array (ndata.length); for (var i = 0; i < text.length; i++) { Buffer[i] = ndata.charcodeat (i); }
Converts a buffer object to a BLOB data type var blob = GetBlob ([buffer]);
var fd = new FormData (), XHR = new XMLHttpRequest (); Fd.append (' file ', blob);
Xhr.open (' post ', url); Xhr.onreadystatechange = function () { Do something } Xhr.send (FD); |
There is a need for compatibility processing in new BLOB objects, especially for andriod machines that do not support formdata upload blobs. The exact method, please poke me.
The main implementation details are by overriding the HTTP request.