var filechooser = document.getElementById ("choose"); Canvas var canvas for compressing pictures = document.createelement ("Canvas"); var ctx = Canvas.getcontext (' 2d '); Tile canvas var Tcanvas = document.createelement ("Canvas"); var tctx = Tcanvas.getcontext ("2d"); var maxsize = 100 * 1024; var Orientation = null; $ ("#upload"). On ("click", Function () {Filechooser.click (); }). On ("Touchstart", function () {$ (this). addclass ("Touch")}). On ("Touchend", function () {$ (this). Removeclass ("Touch")}); Filechooser.onchange = function () {if (!this.files.length) return; var files = Array.prototype.slice.call (this.files); if (Files.length > 9) {alert ("up to 9 images can be uploaded at the same time"); Return } files.foreach (function (file, i) {if (!/\/(?: jpeg|png|gif)/i.test (File.type)) return; Exif.getdata (file, function () {exif.getalltags (this); Orientation = Exif.gettag (this, ' Orientation '); }); var reader = new FileReader (); var li = document.createelement ("li");//Get picture size var size = file.size/1024 > 1024? (~ ~ (file.size/1024/1024))/ten + "MB": ~ ~ (file.size/1024) + "KB"; li.innerhtml = ' <div class= "Progress" ><span></span></div><a href= "javascript:void (0);" title= "data-index=" ' +i+ ' "onclick=" delpic (' +i+ ') "></a>"; $ (". Img-list"). Append ($ (LI)); Reader.onload = function () {var result = This.result; var img = new Image (); IMG.SRC = Result;/**if (Navigator.userAgent.match (/iphone/i)) {if (Orientation! = "" && Orientation! = 1) {//a Lert (' rotation processing '); Switch (Orientation) {case 6://need to rotate//alert clockwise (left) 90 degrees (' need to go left '); img.src = Rotateimg (img, ' ieft ', canvas); Console.log (IMG.SRC); Case 8://needs to rotate counterclockwise (right) by 90 degrees Console.log (' need to Right '); IMG.SRC = Rotateimg (img, ' "," canvas); Break Case 3://requires a 180 degree rotation console.log (' 180 degrees '); IMG.SRC = Rotateimg (img, ' right ', CanvAS);//Turn two times IMG.SRC = Rotateimg (img, ' right ', canvas); Break }}}**/$ (LI). css ("background-image", "url (" + img.src + ")"); $ (LI). css ("background-image", "url (" + result + ")"), $ (LI). css ("Background-size", "100% 100%"), $ (LI). attr (' id ', ' Uploadimg_ ' +i); If the image size is less than 100kb, upload directly if (result.length <= maxsize) {//img = null; result = IMG.SRC; Upload (result, File.type, $ (LI), i); Return }//the picture is loaded and then compresses, then uploads if (Img.complete) {callback (); } else {img.onload = callback; } function callback () {var data = compress (IMG); Upload (data, File.type, $ (LI), i); img = NULL; } }; Reader.readasdataurl (file); }) }; function Rotateimg (img, Direction,canvas) {//alert (IMG); Minimum and maximum rotation direction, the picture rotates 4 times and then returns to the original direction var min_step = 0; var max_step = 3; var img = document.getElementById (PID); if (img = = null) return; The height and width of the IMG cannot be obtained after the IMG element is hidden, otherwise there will be an error var height = img.height; var width = img.width; var step = img.getattribute (' step '); var step = 2; if (step = = NULL) {step = Min_step; } if (direction = = ' right ') {step++; Rotate to the original position, which exceeds the maximum value of step > Max_step && (step = min_step); } else {step--; Step < Min_step && (step = max_step); }//Rotation angle with a radian value of var degree = step * * * * MATH.PI/180; var ctx = Canvas.getcontext (' 2d '); Switch (step) {Case 0:canvas.width = width; Canvas.height = height; Ctx.drawimage (IMG, 0, 0); Break Case 1:canvas.width = height; Canvas.height = width; Ctx.rotate (degree); Ctx.drawimage (IMG, 0,-height); Break Case 2:canvas.width = width; Canvas.height = height; Ctx.rotate (degree); Ctx.drawimage (IMG,-width,-height); Break Case 3:canvas.width = height; Canvas.height = width; Ctx.rotate (degree); Ctx.drawimage (IMG,-width, 0); Break }var ndata = Canvas.todataurl (' image/jpeg '); return ndata; }//delete//use canvas to compress the large picture function delpic (i) {$ ("#content" +i). Remove (); $ ("#uploadImg_" +i). Remove (); Function Compress (img) {var initsize = img.src.length; var width = img.width; var height = img.height; If the picture is greater than 4 million pixels, calculate the compression ratio and press the size to 4 million VAR ratio; if ((ratio = width * height/4000000) > 1) {ratio = MATH.SQRT (RatiO); Width/= ratio; Height/= ratio; } else {ratio = 1; } canvas.width = width; Canvas.height = height;//Floor Ctx.fillstyle = "#fff"; Ctx.fillrect (0, 0, canvas.width, canvas.height); If the picture pixel is greater than 1 million, use the tile to draw var count; if (count = width * height/1000000) > 1) {count = ~ ~ (math.sqrt (count) + 1);//Calculate how many tiles to divide//calculate the width of each tile and high var NW = ~ ~ (width/count); var NH = ~ ~ (height/count); Tcanvas.width = NW; Tcanvas.height = NH; for (var i = 0; i < count; i++) {for (var j = 0; J < Count; J + +) {tctx.drawimage (img, I * NW * rat IO, J * nh * ratio, NW * ratio, NH * ratio, 0, 0, NW, NH); Ctx.drawimage (Tcanvas, I * NW, J * NH, NW, NH); }}}} else {Ctx.drawimage (img, 0, 0, width, height); }//Minimum compression var ndata = Canvas.todataurl (' Image/jpeg ', 0.1); Console.log (' Pre-compression: ' + initsize); Console.log (' after compression: ' + ndata.length '); Console.log (' compression ratio: ' + ~~ (+ * (initsize-ndata.length)/initsize) + "%"); Tcanvas.width = Tcanvas.height = Canvas.width = Canvas.height = 0; return ndata; }//image upload, turn base64 's image into binary object, plug in formdata upload function upload (basestr, type, $li, index) {var text = Window.atob (basest R.split (",") [1]); var buffer = new Uint8array (text.length); var pecent = 0, loop = null; for (var i = 0; i < text.length; i++) {Buffer[i] = text.charcodeat (i); } var blob = GetBlob ([buffer], type); var xhr = new XMLHttpRequest (); var formdata = Getformdata (); Formdata.append (' ImageFile ', blob); Xhr.open (' Post ', './ajax_image '); Xhr.onreadystatechange = function () {if (xhr.readystate = = 4 && Xhr.status = =) {//var Jsondata = $.parsejson (Xhr.responsetext); var obj = eval ("(" +xhr.responsetext+ ")"); Console.log (Obj.path); if (obj.iresult==1) {var html = ' <input type= "hidden" value= "' +obj.path+ '" name= "content[]" id= "Content ' +index+ '" > '; $ ("#photofile"). AppEnd (HTML);} Else{alert (' upload failed ');} var text = obj.iresult==1? ' Upload success ': ' Upload failed '; Console.log (text + ': ' + Obj.path); Clearinterval (loop); When the message is received $li. Find (". Progress"). Animate ({' width ': ' 100% '}, pecent < 95? 200:0, Function () {$ (this). html (text); }); if (!obj.path) return; $ (". Pic-list"). Append (' <a href= "' + Imagedata.path + '" > ' + imagedata.name + ' (' + imagedata.size + ') </a> '); } }; Data transmission progress, the first 50% shows the Progress Xhr.upload.addEventListener (' Progress ', function (e) {if (loop) return; Pecent = ~ ~ (e.loaded/e.total)/2; $li. Find (". Progress"). CSS (' width ', pecent + "%"); if (pecent = =) {mockprogress (); }}, False); Data after 50% with the simulation progress function mockprogress () {if (loop) return; loop = SetInterval (function () {pecent++; $li. Find (". Progress"). CSS (' width ', pecent + "%"); if (peceNT = =) {clearinterval (loop); }}, (+)} xhr.send (Formdata); }/** * Get the Blob object compatibility notation * @param buffer * @param format * @returns {*} * * Function GetBlob (buffer, format) { try {return new Blob (buffer, {type:format}); } catch (e) {var bb = new (window. Blobbuilder | | Window. Webkitblobbuilder | | Window. Msblobbuilder); Buffer.foreach (function (buf) {bb.append (BUF); }); return Bb.getblob (format); }}/** * get Formdata */function Getformdata () {var isneedshim = ~navigator.useragent.indexof (' Android ') && ~navigator.vendor.indexof (' Google ') &&!~navigator.useragent.indexof (' Chrome ') && ; Navigator.userAgent.match (/applewebkit\/(\d+)/). Pop () <= 534; Return Isneedshim? New Formdatashim (): New FormData ()}/** * FormData patch for Android that does not support FormData upload blob * @constructor */functio n Formdatashim () {Console.warn (' using Formdata shim '); VaR o = this, parts = [], boundary = Array (+). Join ('-') + (+new Date () * (1E16 * math.random ())). ToString (36) , oldsend = XMLHttpRequest.prototype.send; This.append = function (name, value, filename) {Parts.push ('---' + boundary + ' \r\ncontent-disposition:form-data; nam E= "' + name + '" '); if (value instanceof Blob) {Parts.push ('; filename= ' + (filename | | ' blob ') + ' "\r\ncontent-type: ' + value.type + ' \r\n\r\n '); Parts.push (value); } else {Parts.push (' \r\n\r\n ' + value); } parts.push (' \ r \ n '); }; Override XHR Send () XMLHttpRequest.prototype.send = function (val) {var fr, data, OXHR = this ; if (val = = = O) {//Append the final boundary string Parts.push ('---' + boundary + '--\r\n '); Create the BLOB data = GetBlob (parts); Set up and read the Blob into a array to be sent FR = new FileReader (); Fr.onload = function () { Oldsend.call (OXHR, Fr.result); }; Fr.onerror = function (err) {throw err; }; Fr.readasarraybuffer (data); Set the multipart content type and boudary this.setrequestheader (' Content-type ', ' multipart/form-data; boundary= ' + boundary); XMLHttpRequest.prototype.send = Oldsend; } else {Oldsend.call (this, Val); } }; }
JS picture front-End compression multi-image upload (rotation is actually good, but the phone side has a problem to first compression and then rotation)