Heim > Web-Frontend > H5-Tutorial > Hauptteil

Detaillierte Einführung in HTML5 Canvas-Bild- und Textcode zur Verarbeitung von Avatar-Uploads

黄舟
Freigeben: 2017-03-07 16:02:15
Original
1687 Leute haben es durchsucht

Seit kurzem muss das Community-System das mobile Endgerät unterstützen, was das Hochladen von Benutzer-Avataren erfordert. Die Avatare gibt es in drei Größen: groß, mittel und klein. Auf der PC-Seite verwendet die Community Flash Behandeln Sie die Avatar-Bearbeitung und -Generierung, aber die Flash-Steuerung Die Benutzeroberfläche ist unfreundlich und das mobile Endgerät unterstützt Flash nicht gut. In Anbetracht dieser Probleme haben wir uns schließlich für Canvas entschieden, um die Skalierung der Bildgröße und die Bilddatenerfassung abzuschließen.

Gleichseitige Verarbeitung

Avatare sind im Allgemeinen quadratisch. Zuerst müssen wir den Mindestwert für die Breite und Höhe des Bildes ermitteln und den Mindestwert als Seitenlänge für den Mittelzuschnitt verwenden Bild, und schließlich ein quadratisches Bild erhalten:

var ImageEditor = function() {
    // 用离线canvas处理图片数据
    this.canvas = document.createElement('canvas');
    this.context = this.canvas.getContext('2d');
};
var fn = ImageEditor.prototype;
fn.resizeCanvas = function(width, height) {
    this.canvas.width = width;
    this.canvas.height = height;
};
fn.clipSquareImage = function(url, callback) {
    var that = this,
        img = new Image();
    img.src = url;
    img.onload = function() {
        // 取宽高最小值作为正方形边长
        var eLength = Math.min(img.width, img.height),
            picture = img;
        // canvas不支持局部截屏,截屏前必须先调节canvas的宽高
        that.resizeCanvas(eLength, eLength);
        // 将图片以居中裁剪的方式画到canvas中。
        // drawImage支持9个参数:图片对象,图片上的剪切坐标XY,
        // 剪切宽高,图片在canvas上的坐标XY及图片宽高
        that.context.drawImage(picture,
            (picture.width - eLength) / 2, (picture.height - eLength) / 2,
            eLength, eLength, 0, 0, eLength, eLength);
        // 截屏,即获取base64数据
        callback.call(that, that.canvas.toDataURL('image/png'));
    };
};
Nach dem Login kopieren

Problem mit der Größenbeschränkung des Leinwandelements

In der obigen clipSquareImage-Funktion, da die canvas.toDataURL-Schnittstelle keine Breite und Höhe bereitstellt Parameter können nur die gesamten Canvas-Bildschirmdaten auf einmal erfassen. Bevor wir also einen Screenshot des Canvas erstellen, müssen wir zunächst die Größe des Canvas-Elements festlegen. Allerdings ist die Auflösung mobiler Fotos extrem hoch und die Breite und Höhe liegen meist über 3000. Wenn wir die Größe der Leinwand basierend auf der Mindestbreite und -höhe des Fotos festlegen, beträgt die Mindestbreite des Canvas-Elements auch hoch wie über 3000.

Das Problem besteht darin, dass jede Plattform Beschränkungen hinsichtlich der Größe der Leinwand hat. Wenn entweder die Breite oder Höhe der Leinwand die Plattformbeschränkung überschreitet, kann die Leinwand nicht gerendert werden, und zwar canvas.toDataURL Erhalten Sie transparente Bilddaten.

Die maximale Größe eines Canvas-Elements gibt die Größenbeschränkung von Canvas auf einigen Plattformen an:

chrome          = 32767x32767
iPod Touch 16GB = 1448x1448
iPad Mini       = 2290x2289
iPhone 3        = 1448x1448
iPhone 5        = 2290x2289
Nach dem Login kopieren

Anhand der oben genannten Daten legen wir zunächst eine maximale Breite für Canvas fest:

var MAX_WIDTH = 1000;
Nach dem Login kopieren

Fügen Sie der Funktion clipSquareImage die Erkennung maximaler Breite hinzu. Wenn die Grenze überschritten wird, erstellen Sie eine temporäre Leinwand für die Bildskalierung und schneiden Sie die temporäre Leinwand schließlich mittig aus:

fn.clipSquareImage = function(url, callback) {
    var that = this,
        img = new Image();
    img.src = url;
    img.onload = function() {
         // 取图片宽高和Canvas的最大宽度的最小值作为等边长
        var eLength = Math.min(img.width, img.height, MAX_WIDTH),
            // 剪切对象
            picture = img,
            tempEditor,
            ratio;
            // 如果图片尺寸超出限制
            if (eLength === MAX_WIDTH) {
                // 创建一个临时editor
                tempEditor = new ImageEditor();
                ratio = img.width / img.height;
                // 按图片比例缩放canvas
                img.width < img.height ?
                    tempEditor.resizeCanvas(MAX_WIDTH * ratio, MAX_WIDTH) :
                    tempEditor.resizeCanvas(MAX_WIDTH, MAX_WIDTH / ratio);
                tempEditor.context.drawImage(img, 0, 0, tempEditor.canvas.width, tempEditor.canvas.height);
                // 将临时Canvas作为剪切对象
                picture = tempEditor.canvas;
                eLength = Math.min(tempEditor.canvas.width, tempEditor.canvas.height);
            }
            // 居中剪切
            // ... ...
            // 截屏操作
            // ... ...
    };
};
Nach dem Login kopieren

Canvas-Aliasing Problem

Oben konnten wir ein quadratisches Bild über Canvas zuschneiden. Als nächstes müssen wir uns mit den drei Größen des Avatar-Bildes befassen: groß, mittel und klein. In Canvas bietet die drawImage-Schnittstelle eine sehr praktische Skalierungsfunktion:

var editor = new ImageEditor;
// 将图片缩放到300x300
// drawImage支持5个参数:图片对象,及图片在canvas上的坐标和宽高
editor.context.drawImage(squareImage, 0, 0, 300, 300);
Nach dem Login kopieren

Die direkte Verwendung von drawImage zum Verkleinern großer Bilder führt jedoch dazu, dass das Bild gezackt erscheint. Bei einem Stapelüberlauf schlug HTML5 Canvas DrawImage: How to Apply Antialiasing eine Lösung vor: Reduzieren Sie das Bild mehrmals in gleichen Anteilen und vergrößern Sie es schließlich auf die Zielgröße:

Detaillierte Einführung in HTML5 Canvas-Bild- und Textcode zur Verarbeitung von Avatar-Uploads

Referenz In dieser Lösung können wir die Anti-Aliasing-Skalierungsfunktion antialiasScale implementieren:

fn.antialisScale = function(img, width, height) {
    var offlineCanvas = document.createElement(&#39;canvas&#39;),
        offlineCtx = offlineCanvas.getContext(&#39;2d&#39;),
        sourceWidth = img.width,
        sourceHeight = img.height,
        // 缩小操作的次数
        steps = Math.ceil(Math.log(sourceWidth / width) / Math.log(2)) - 1,
        i;
    // 渲染图片
    offlineCanvas.width = sourceWidth;
    offlineCanvas.height = sourceHeight;
    offlineCtx.drawImage(img, 0, 0, offlineCanvas.width, offlineCanvas.height);
    // 缩小操作
    // 进行steps次的减半缩小
    for(i = 0; i < steps; i++) {
        offlineCtx.drawImage(offlineCanvas, 0, 0,
            offlineCanvas.width * 0.5, offlineCanvas.height * 0.5);
    }
    // 放大操作
    // 进行steps次的两倍放大
    this.context.drawImage(offlineCanvas, 0, 0,
        offlineCanvas.width * Math.pow(0.5, steps), 
        offlineCanvas.height * Math.pow(0.5, steps),
        0, 0, width, height);
};
Nach dem Login kopieren

Wir können diese Funktion anstelle von drawImage verwenden, um die Skalierungsarbeit abzuschließen und drei Größen von Avatar-Bildern zu generieren:

fn.scaleSquareImage = function(url, sizes, callback) {
    var that = this;
    // 先裁剪一个正方形
    that.clipSquareImage(url, sizes, function(data) {
        var squareImage = new Image(),
            result = [],
            i;
        squareImage.src = data;
        // 抗锯齿缩放
        for (i = 0; i < sizes.length; i++) {
            that.antialisScale(squareImage, sizes[i], size[i]);
            result.push(that.canvas.toDataURL(&#39;image/png&#39;));    
        }
        callback.call(that, result);
    });
};
Nach dem Login kopieren

PHP speichert Base64-Bilddaten

Canvas.toDataURL()Das erhaltene Standard-Bilddatenformat ist: data:image/png;base64, + Base64-Daten:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC
Nach dem Login kopieren

Wenn die Canvas-Screenshot-Daten vorliegen an den Hintergrund übergeben, der Hintergrund Sie müssen das Startfeld data:image/png;base64, abschneiden, um die echten Base64-Daten zu erhalten:

<?php
    $imgData = $_POST[&#39;imgData&#39;];
    // 截取有用的部分
    list($type, $imgData) = explode(&#39;;&#39;, $imgData);
    list(, $imgData)      = explode(&#39;,&#39;, $imgData);
    // base64 编码中使用了加号,
    // 如果通过url传递base64数据,+号会转换成空格
    $imgData = str_replace(&#39; &#39;, &#39;+&#39;, $imgData);
    // 存储文件
    $success = file_put_contents(&#39;PATH/XXX.png&#39;, base64_decode($imgData));
Nach dem Login kopieren

Referenz

  • Speichern Sie eine Base64-Verschlüsselung Leinwandbild in eine PNG-Datei mit PHP

  • Html5 Canvas DrawImage: So wenden Sie Antialiasing an

  • Maximale Größe eines Leinwandelements

  • So speichern Sie ein PNG-Bild serverseitig aus einer Base64-Datenzeichenfolge

  • So senden Sie FormData-Objekte mit Ajax-Anfragen in jQuery

Das Obige ist die detaillierte Einführung des Bild- und Textcodes von HTML5 Canvas für die Verarbeitung des Avatar-Uploads. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!



Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!