Questions: in the near future, we need to make a demand for the front-end to obtain images and compress them, then upload them to the back-end server or upload them to oss, and then transfer the path to the back-end server. During compression, it is found that the system at or below IOS 10 is invalid. After verification, this is because when using the HTML canvas element. Toblob() method of canvas to create blob objects, there is no system at or below IOS 10 Method call.
Answer:
1. Realize front-end compression and upload
(1) HTML: picture preview box & input upload control
<div id="uploader"> <!-- Show preview picture --> <!-- <div class="img_show"></div> --> <!-- Picture upload --> <div id="fileInput" class="img_uploader"> <input id="imgUpload" type="file" name="imgs" accept="image/*"> </div> </div>
(2) Image upload and compression
// formdata object of form upload var fd = new FormData(); // canvas for compressing pictures var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var img = new Image(); var file = null; // Image objects uploaded by users /* Click input to upload the picture */ $("#fileupload").on('change', function (e) { file = event.target.files[0]; // Picture preview, load base64 picture var reader = new FileReader(); reader.onload = (function (file) { return function (e) { var datainfo = this.result; img.src = datainfo; var html = '<div class="img_show" style="background-image:url('+ datainfo +')"></div>' $("#uploader").prepend(html); if ($("#uploader .img_showCurrent").length >= 2) { $("#fileInput").hide(); } }; })(e.target.files[0]); reader.readAsDataURL(e.target.files[0]); // After loading base64 address image, draw canvas compressed image img.onload = function () { // Picture original size var originWidth = this.width; var originHeight = this.height; // Maximum size limit var maxWidth = 800, maxHeight = 800; // Target size var targetWidth = originWidth, targetHeight = originHeight; // Picture size exceeds the limit of 400x400 if (originWidth > maxWidth || originHeight > maxHeight) { if (originWidth / originHeight > maxWidth / maxHeight) { // Wider, size by width targetWidth = maxWidth; targetHeight = Math.round(maxWidth * (originHeight / originWidth)); } else { targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight)); } } // canvas zooms the picture canvas.width = targetWidth; canvas.height = targetHeight; // Clear canvas ctx.clearRect(0, 0, targetWidth, targetHeight); // Picture compression ctx.drawImage(img, 0, 0, targetWidth, targetHeight); // When there is no toBlob method in the canvas object prototype, add it manually if (!HTMLCanvasElement.prototype.toBlob) { Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { value: function (callback, type, quality) { var binStr = atob( this.toDataURL(type, quality).split(',')[1] ), len = binStr.length, arr = new Uint8Array(len); for (var i=0; i<len; i++ ) { arr[i] = binStr.charCodeAt(i); } callback( new Blob( [arr], {type: type || 'image/png'} ) ); } }); } // canvas to blob and upload canvas.toBlob(function (blob) { fd.append('pic', blob) }, file.type||'image/png'); }; })
(3) Upload picture
fd.append("uid", uids); $.ajax({ type: "post", url: baseUrl + "xxxx/xxxxx", data: fd, dataType: "json", processData: false, // processData and contentType need to be set to false contentType: false, async: false, success: function (res) { // ... ... } })
2. Compatible with ios10 system
// When there is no toBlob method in the canvas object prototype, add it manually if (!HTMLCanvasElement.prototype.toBlob) { Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { value: function (callback, type, quality) { var binStr = atob( this.toDataURL(type, quality).split(',')[1] ), len = binStr.length, arr = new Uint8Array(len); for (var i=0; i<len; i++ ) { arr[i] = binStr.charCodeAt(i); } callback( new Blob( [arr], {type: type || 'image/png'} ) ); } }); }