Dieses Problem ergibt sich aus der Tatsache, dass beim Hochladen von Bilddateien die Größe des Hintergrunds auf 2 MB begrenzt ist, diese jedoch beim Einschalten der Kamera zum Aufnehmen von Bildern jede Minute 2 MB überschreitet. Um das Benutzererlebnis und die Funktionsanforderungen nicht zu beeinträchtigen Das Frontend muss die Größe komprimieren und dann hinter die Bühne hochladen.
IdeenanalyseNachdem ich viele Informationen durchsucht hatte, stellte ich fest, dass nur Canvas Bilder komprimieren kann.
Das Prinzip ist ungefähr wie folgt: 1. Konvertieren Sie zunächst die Dateidatei des Bildes in baseURL. 2. Erstellen Sie ein Bild-Tag, um die Datei zu empfangen und die Breite, Höhe und Proportionen des Bildes zu ermitteln. 3. Erstellen Sie eine Leinwand und legen Sie die Größe der Leinwand fest. 4. Zeichnen Sie das Bild auf die Leinwand. 5. Komprimieren Sie die Leinwand und erhalten Sie eine neue Basis-URL. 6. Konvertieren Sie die Basis-URL zurück in eine Datei.
Funktion der Prämisse Konvertieren Sie die Datei in Base64/*** @param {binärer Dateistream} file * @param {callback function, return base64} fn */function changeFileToBaseURL(file,fn){ // Ein Lesedateiobjekt erstellen var fileReader = new FileReader(); Wenn die Datei nicht definiert ist, geben Sie null zurück if(file == undefiniert) return fn(null); // Lesen Sie die Datei file, das Ergebnis ist base64-bit fileReader.readAsDataURL(file); fileReader.onload = function(){ // Lesen Sie die Base64-Variable imgBase64Data = this.result;Konvertieren Sie Base64 in einen Dateistream
/** * Base64 in Datei konvertieren * @param {baseURL} dataurl * @param {Dateiname} Dateiname * @return {Datei-Binärstream}*/function dataURLtoFile(dataurl, filename) { 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 File([u8arr], filename, {type:mime});Komprimierungsmethode
/*** Canvas-komprimiertes Bild* @param {Parameter obj} param * @param {Datei-Binärstream} param.file erforderlich* @param {Zielkomprimierungsgröße} param.targetSize übergibt die anfängliche Zuweisung nicht -1* @param {output Bildbreite} param.width übergibt nicht den anfänglichen Zuweisungswert -1 und übergibt nicht die Höhe für die proportionale Skalierung* @param {Ausgabebildname} param.fileName übergibt nicht die anfängliche Zuweisung image* @param {komprimierter Bildgrad } param.quality überschreitet nicht den anfänglichen Zuweisungswert von 0,92. Wertebereich 0~1* @param {callback function} param.succ erforderlich */function pressImg(param){ //Wenn keine Callback-Funktion vorhanden ist, wird diese nicht ausgeführt if(param && param.succ){ //If Datei ist nicht definiert, null zurückgeben if(param.file == undefiniert) return param.succ(null); //Anfangswert an den Parameter anhängen param.targetSize = param.hasOwnProperty(targetSize)? param.targetSize : -1; param.width = param.hasOwnProperty( Qualität) ? param.quality : 0.92; var _this = this; // Den Dateityp var fileType abrufen = param.file.type; // console.log(fileType) //image/jpeg if(fileType.indexOf(image) == -1){ console.log('Bitte wählen Sie eine Bilddatei^_^'); return param.succ(null); } //Wenn die aktuelle Größe kleiner als die Zielgröße ist, direkt ausgeben var size = param.file.size; if(param.targetSize > size){ return param.succ(param.file ); } / / Lesen Sie die Datei file und das Ergebnis ist base64 changeFileToBaseURL(param.file,function(base64){ if(base64){ var image = new Image(); image.src = base64; image.onload = function(){ // Get das Seitenverhältnis var scale = this.width / this.height; // console.log(scale) //Erstelle eine Leinwand var canvas = document.createElement('canvas'); //Erhalten Sie den Kontext var context = canvas.getContext('2d'); //Erhalten Sie die Breite des komprimierten Bildes -1, die Standardbreite des ursprünglichen Bildes. width: param.width; //Ermitteln Sie die Höhe des komprimierten Bildes. Wenn die Breite -1 beträgt, ist die Standardhöhe des ursprünglichen Bildes canvas.height = param.width == -1. parseInt(param.width / scale); //Zeichne das Bild auf die Leinwand context.drawImage(image, 0, 0, canvas.width, canvas.height); //Komprimiere das Bild und erhalte eine neue base64Url var newImageData = canvas .toDataURL(fileType,param.quality); //Base64 in einen Dateistream konvertieren var resultFile = dataURLtoFile(newImageData,param.fileName); //Beurteilen, ob targetSize begrenzt ist und die komprimierte Bildgröße größer als die Zielgröße ist, wird ein Fehler angezeigt if(param.targetSize != -1 && param.targetSize < resultFile.size ){ console .log(Die Bild-Upload-Größe ist zu groß, bitte erneut hochladen^_^); //Dateistream zurückgeben param.succ(resultFile); } } } });Methodenverwendung
Die Größe der Datei wird in Bytes angegeben, daher müssen wir die erforderliche Größe in Bytes umrechnen. 1 Byte ist 1 Byte ist 1B, 1KB = 1024B, 1MB = 1024 * 1024B
<input type=file id=fileImg class=fileImg/>
//Bilddatei-Upload-URL abrufen$(#fileImg).on('change',function(){ pressImg({ file:this.files[0], targetSize:2 * 1024 * 1024, quality:0.5, width:600 , succ:function(resultFile){ //Wenn es nicht null ist, ist die Komprimierung erfolgreich if(resultFile){ //TODO } } })});Problemzusammenfassung Bildkomprimierungsstufe
Der Komprimierungsgrad des Bildes ist nicht einfach zu bestimmen, daher können Sie es mehrmals ausprobieren und an die Anforderungen des Nachfragers anpassen. Durch Ändern der Größe und Auflösung des Zielbilds kann sich der Grad der Bildkomprimierung ändern.
Ursprünglich wollte ich einen rekursiven Prozess zum Komprimieren von Bildern durchführen, bis die Bildgröße den Erwartungen entspricht.Später herausgefunden
Denn wenn iOS die Systemkamera zum Fotografieren aufruft, wird diese um 90 Grad gegen den Uhrzeigersinn gedreht. Nachdem ich das Bild komprimiert und in den Hintergrund geschickt hatte, stellte ich fest, dass die Aufnahmerichtung der Exif-Informationen des Bildes verloren ging, was dazu führte, dass die von iOS hochgeladenen Bilder um 90 Grad gegen den Uhrzeigersinn gedreht wurden. Android hat dieses Problem noch nie bemerkt.
Derzeit besteht der Verdacht, dass es bei der Konvertierung von Base64 in eine Dateidatei verloren gegangen ist. Weitere Anweisungen werden hier nach der Überprüfung bereitgestellt.
@version1.0-2019-8-2-Create „Canvas zum Komprimieren der Bildgröße verwenden“
©burning_Yun Qiqi
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.