Heim > Web-Frontend > H5-Tutorial > Vollständiges Beispiel für das Zoomen und Hochladen von Bildern über Canvas und File API_html5-Tutorial-Fähigkeiten

Vollständiges Beispiel für das Zoomen und Hochladen von Bildern über Canvas und File API_html5-Tutorial-Fähigkeiten

WBOY
Freigeben: 2016-05-16 15:49:07
Original
1589 Leute haben es durchsucht

Beispieladresse: Canvas Resize Demo
Originalautor: Dr. Tom Trenka
Originaldatum: 6. August 2013
Übersetzungsdatum: 8. August 2013

Tom Trenka Es ist mir eine große Ehre, einen Artikel für „meinen“ Blog schreiben zu dürfen. Tom war einer der ursprünglichen Mitwirkenden am Dojo-Framework und mein Mentor bei SitePen. Ich habe seine Genialität auf höchstem Niveau erlebt und er war immer der Erste, der viele schwierige Probleme mit zukunftsweisenden Lösungen vorhergesehen hat. Er denkt immer von außen und löst Randprobleme auf unkonventionelle, aber solide Weise. Dieser Artikel ist ein perfektes Beispiel.
In letzter Zeit wurde ich häufig nach der Erstellung einer Benutzeroberflächen-API gefragt, mit der Benutzer (unter anderem) Bilder auf einen Server hochladen und auf der Clientseite der zahlreichen von unserem Unternehmen unterstützten Websites verwendet werden können. Normalerweise ist dies eine sehr einfache Sache: Erstellen Sie ein Formular, fügen Sie ein Eingabefeld für den Dateityp hinzu, lassen Sie den Benutzer ein Bild vom Computer auswählen und legen Sie das Formular enctype="multipart/form-data" in den Formular-Tag-Eigenschaften fest und laden Sie es dann hoch . Ziemlich einfach, nicht wahr? Tatsächlich ist hier ein recht einfaches Beispiel; Klicken Sie, um einzutreten
Aber was ist, wenn Sie das Bild vor dem Hochladen auf irgendeine Weise vorverarbeiten möchten? Beispielsweise müssen Sie zuerst die Bildgröße komprimieren, oder Sie möchten, dass das Bild nur in bestimmten Formattypen wie PNG oder JPG vorliegt. Was sollten Sie tun?
Verwenden Sie Canvas, um das Problem zu lösen!

Einführung in Canvas
Canvas ist ein neues DOM-Element in HTML5, das es Benutzern ermöglicht, Grafiken direkt auf der Seite zu zeichnen, normalerweise mit JavaScript. Verschiedene Formatstandards sind beispielsweise unterschiedlich. SVG ist beispielsweise eine Raster-API (Raster-API), während VML eine Vektor-API ist. Sie können Adobe Illustrator (Vektor) zum Zeichnen und Adobe Photoshop (Raster) zum Zeichnen verwenden.

Auf der Leinwand können Sie Bilder lesen und rendern und Bilddaten über JavaScript bearbeiten. Es gibt viele vorhandene Artikel, die die grundlegende Bildverarbeitung für Sie demonstrieren und sich hauptsächlich auf verschiedene Bildfiltertechniken konzentrieren. Wir müssen jedoch lediglich das Bild skalieren und in ein bestimmtes Dateiformat konvertieren, und Canvas kann diese Aufgaben vollständig übernehmen.

Unsere angenommenen Anforderungen, z. B. dass die Bildhöhe 100 Pixel nicht überschreitet, unabhängig von der Höhe des Originalbilds. Der Grundcode lautet wie folgt:

Kopieren Sie den Code
Der Code lautet wie folgt:

// Parameter, maximale Höhe
var MAX_HEIGHT = 100;// Rendering
function render(src){
// Ein Bildobjekt erstellen
var image = new Image() ;
// Den Load-Event-Handler binden und nach Abschluss des Ladevorgangs ausführen
image.onload = function(){
// Das Canvas-DOM-Objekt abrufen
var canvas = document.getElementById("myCanvas ");
// Wenn die Höhe den Standard überschreitet
if(image.height > MAX_HEIGHT) {
// Breite proportionale Skalierung *=
image.width *= MAX_HEIGHT / image.height ;
image.height = MAX_HEIGHT;
}
// Holen Sie sich das 2D-Umgebungsobjekt von Canvas,
// Es ist verständlich, dass Context der Administrator und Canvas das Haus ist
var ctx = canvas.getContext("2d"); 🎜>canvas.width = image.width;
canvas.height = image.height;
// Zeichne das Bild auf die Leinwand
ctx.drawImage(image, 0, 0, image.width, image .height);
// !!! Beachten Sie, dass das Bild nicht zum Dom hinzugefügt wird
// Legen Sie das src-Attribut fest und der Browser lädt es automatisch.
// Denken Sie daran, dass das Ereignis zuerst gebunden werden muss, bevor das src-Attribut festgelegt werden kann, da sonst Synchronisierungsprobleme auftreten.
image.src = src;
};
Im obigen Beispiel können Sie die toDataURL()-Methode von Canvas verwenden, um den Base64-codierten Wert des Bildes zu erhalten (der ebenfalls als hexadezimale Zeichenfolge oder binärer Datenstrom verstanden werden kann).
Hinweis: toDataURL von Canvas () Die erhaltene URL beginnt mit einer Zeichenfolge und enthält 22 nutzlose Daten „data:image/png;base64“, die im Prinzip auf dem Client oder Server gefiltert werden müssen URL-Adresse Es gibt keine Längenbeschränkung und die Längenbeschränkung von 1024 gilt nur für die ältere IE-Generation.

Entschuldigung, wie bekommen wir die Bilder, die wir brauchen?
Guter Junge, ich freue mich, dass du gefragt hast. Sie können es nicht direkt über das Dateieingabefeld verarbeiten. Alles, was Sie von diesem Dateieingabefeldelement erhalten können, ist nur der Pfad zu der vom Benutzer ausgewählten Datei. Nach herkömmlicher Vorstellung können Sie Bilder über diese Pfadinformationen laden, dies ist jedoch im Browser unrealistisch. (Anmerkung des Übersetzers: Browserhersteller müssen sicherstellen, dass ihre Browser absolut sicher sind, um Marktanteile zu gewinnen und zumindest Medienangriffe zu vermeiden. Wenn dies zulässig ist, können bösartige URLs versuchen, durch Zusammenfügen von Dateipfaden an bestimmte vertrauliche Informationen zu gelangen.) >Um diese Anforderung zu erfüllen, können wir die Datei-API von HTML5 verwenden, um Dateien auf der Festplatte des Benutzers zu lesen und diese Datei als Quelle des Bildes (src, Quelle) zu verwenden


Einführung in die Datei-API
Die neue Datei-API-Schnittstelle ist eine Möglichkeit, Benutzerdateiverzeichnisse zu lesen und aufzulisten, ohne gegen Sicherheits-Sandbox-Regeln zu verstoßen – durch Sandbox-Einschränkungen können bösartige Websites natürlich keine Viren schreiben. Das Dateileseobjekt, das wir verwenden möchten, heißt FileReader. Mit FileReader können Entwickler den Inhalt von Dateien lesen (die Implementierung bestimmter Browser kann sehr unterschiedlich sein).

Angenommen, wir haben den Pfad der Bilddatei erhalten und uns dann auf den vorherigen Code verlassen, wird es einfach, FileReader zum Laden und Rendern des Bildes zu verwenden:



Code kopierenDer Code lautet wie folgt:
// Bilddatei laden (URL-Pfad)
Funktion LoadImage(src) {
/ / Nicht-Bild-Dateien herausfiltern
if(!src.type.match(/image.*/)){
if(window.console){
console.log( "Ausgewählter Dateityp: Kein Bild: ", src.type); else {
window.confirm("Nur Bilddateien können ausgewählt werden"
return; }
// Erstellen Sie ein FileReader-Objekt und rufen Sie die Renderfunktion auf, um das Rendern abzuschließen.
var reader = new FileReader();
// Binden Sie die automatische Rückruffunktion für das Ladeereignis
reader.onload = function (e){
/ / Rufen Sie die vorherige Renderfunktion auf
render(e.target.result);
// Lesen Sie den Dateiinhalt
reader.readAsDataURL(src);
};


Entschuldigung, wie bekomme ich die Datei?
Kleiner weißer Hase, hab Geduld! Unser nächster Schritt besteht darin, die Datei zu erhalten, und dafür gibt es natürlich viele Möglichkeiten. Beispiel: Sie können ein Textfeld verwenden, um Benutzern die Eingabe von Dateipfaden zu ermöglichen, aber offensichtlich sind die meisten Benutzer keine Entwickler und haben keine Ahnung, welche Werte sie eingeben sollen.
Aus Gründen der Benutzerfreundlichkeit verwenden wir die Drag-and-Drop-API-Schnittstelle .

Verwendung der Drag-and-Drop-API

Die Drag-and-Drop-Schnittstelle (Drag-and-Drop) ist sehr einfach – bei den meisten DOM-Elementen können Sie Event-Handler an die Implementierung binden Wenn der Benutzer eine Datei von der Festplatte auf das Dom-Objekt zieht und die Maus loslässt, können wir die Datei lesen. Der Code lautet wie folgt:



Code kopieren

Der Code lautet wie folgt:
function init(){ // Holen Sie sich das DOM-Elementobjekt var target = document.getElementById("drop-target");
// Verhindern Sie die Zustellung von Dragover-Ereignissen (über das DOM-Element ziehen)
target.addEventListener("dragover", function(e){e.preventDefault();}, true
// Ziehen Sie das Mausereignis und lassen Sie es los
target.addEventListener("drop", function(e); ){
// Standardereignisse und Ereignisweitergabe verhindern
e.preventDefault();
// Rufen Sie die vorherige Ladebildfunktion auf, der Parameter ist die erste Datei des dataTransfer-Objekts
loadImage(e .dataTransfer.files[ 0]);
}, true);
var setheight = document.getElementById("setheight");
var maxheight = document.getElementById("maxheight"); setheight.addEventListener(" click", function(e){
//
var value = maxheight.value;
if(/^d $/.test(value)){
MAX_HEIGHT = parseInt(value);
e.preventDefault();
var btnsend = document.getElementById("btnsend");
btnsend.addEventListener("click ", function(e ){
//
sendImage();
},true);
};


Wir können auch andere Verarbeitungen durchführen, z. B. die Anzeige von Vorschaubildern. Wenn Sie das Bild jedoch nicht komprimieren möchten, ist es wahrscheinlich nutzlos. Wir werden Ajax verwenden, um Bilddaten über die HTTP-Post-Methode hochzuladen. Das folgende Beispiel verwendet das Dojo-Framework, um die Anfrage zu vervollständigen. Natürlich können Sie auch andere Ajax-Technologien verwenden, um sie zu implementieren.
Dojo-Code lautet wie folgt:

Code kopieren
Der Code lautet wie folgt:

// Der Übersetzer versteht Dojo nicht, daher wird die jQuery-Implementierung später angehängt
/ / Denken Sie daran, dass DTK 1.7 AMD ist!
require(["dojo/request"], function(request){
// Legen Sie die Anforderungs-URL, Parameter und Rückrufe fest.
request.post("image -handler.php", {
data: {
imageName: "myImage.png",
imageData: encodeURIComponent(document.getElementById("canvas").toDataURL("image/png"))
}
} ).then(function(text){
console.log("Der Server hat zurückgegeben: ", text);
});

jQuery wird wie folgt implementiert:


Code kopierenDer Code lautet wie folgt:
// Bild hochladen, jQuery-Version
function sendImage(){
// Das Canvas-DOM-Objekt abrufen
var canvas = document.getElementById("myCanvas");
// Get Bei den Base64-codierten Bilddaten ist das Format eine Zeichenfolge
// Am Anfang von „data:image/png;base64,“ muss es auf der Client- oder Serverseite entfernt werden, und die folgenden Teile können geschrieben werden direkt in die Datei.
var dataurl = canvas.toDataURL("image/png");
// URI für Sicherheit kodieren
// data:image/png;base64, beginnend
var imagedata = encodeURIComponent( dataurl) ;
//var url = $("#form").attr("action"); Adresse
// var url = $("input[name='action']").val ();
// 2. Sie können die Attribute eines DOM-Objekts auch direkt verwenden, um
//
// var url = $("#imageaction").attr("action");
// Da es sich um eine Zeichenfolge handelt, muss der Server die Daten transkodieren, Dateioperationen schreiben usw.
// Persönliche Vereinbarung, alle http-Parameternamen sind in Kleinbuchstaben
console.log(dataurl);
//console.log(imagedata);
var data = {
imagename: " myImage .png",
imagedata: imagedata
};
jQuery.ajax( {
url : url,
data : data,
type : "POST",
// Erwarteter Rückgabewerttyp
dataType: "json",
complete : function(xhr,result) {
//console.log(xhr.responseText); "#tip2");
if(!xhr){
$tip2.text('Netzwerkverbindung fehlgeschlagen!');
return false; ;
if(!text){
$tip2.text('Netzwerkfehler!');
return false;
}
var json = eval("(" text ")" );
if(!json){
$tip2.text('Parse error!');
return false; ;
}
//console.dir(json);
//console.log(xhr.responseText);


OK, fertig! Sie müssen lediglich eine einfache Benutzeroberfläche erstellen, mit der Sie die Größe des Bildes steuern können. Die auf den Server hochgeladenen Daten müssen nicht den Enctype von Multipart-/Formulardaten verarbeiten. Es genügt ein einfacher POST-Formularhandler.
Okay, hier ist ein vollständiges Codebeispiel:





Code kopieren

Der Code lautet wie folgt:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() "://" request.getServerName() ":" request.getServerPort() path "/";
%>



通过Canvas及File API缩放并上传图片






<script> <br>// 参数,最大高度 <br>var MAX_HEIGHT = 100; <br>// 渲染 <br>function render(src){ <br>// 创建一个 Image 对象 <br>var image = new Image(); <br>// 绑定 Load 事件处理器,加载完成后执行 <br>image.onload = function(){ <br>// 获取 Canvas DOM 对象 <br>var canvas = document.getElementById("myCanvas") ; <br>// 如果高度超标 <br>if(image.height > MAX_HEIGHT) { <br>// 宽度等比例缩放 *= <br>image.width *= MAX_HEIGHT / image.height; <br>image.height = MAX_HEIGHT; > <br>// Canvas-Funktion <br>ctx.clearRect(0, 0, Canvas.width, Canvas.height); <br>// 重置canvas宽高 <br>canvas.width = image.width; <br>canvas.height = image.height; <br>// 将图像绘制到canvas上 <br>ctx.drawImage(image, 0, 0, image.width, image.height); <br>// !!! 注意,image 没有加入到 dom之中 <br>}; <br>// 设置src属性,浏览器会自动加载步问题。 <br>image.src = src; <br>}; <br>// 加载 图像文件(url路径) <br>function loadImage(src){ <br>// 过滤掉 非 image 类型的文件 <br>if(!src.type.match(/image.*/ )){ <br>if(window.console){ <br>console.log("选择的文件类型不是图片: ", src.type); <br>} else { <br>window.confirm("只能选择图片文件"); <br>} <br>zurück; <br>} <br>// 创建 FileReader 对象 并调用 render 函数来完成渲染. <br>var reader = new FileReader(); <br>// 绑定load事件自动回调函数 <br>reader.onload = function(e){ <br>// 调用前面的 render 函数 <br>render(e.target.result); <br>}; <br>// 读取文件内容 <br>reader.readAsDataURL(src); <br>}; <br>// 上传图片,jQuery版 <br>function sendImage(){ <br>// Canvas DOM anzeigen <br>var canvas = document.getElementById("myCanvas"); <br>// 获取Base64编码后的图像数据,格式是字符串 <br>// "data:image/png;base64,"开头,需要在客户端或者服务器端将其去掉, 后面的部分可以直接写入文件。 <br>var dataurl = canvas.toDataURL("image/png"); <br>// 为安全 对URI进行编码 <br>// data:image/png;base64, 开头 <br>var imagedata = encodeURIComponent(dataurl); <br>//var url = $("#form").attr("action"); <br>// 1. 如果form表单不好处理,可以使用某个hidden隐藏域来设置请求地址 <br>// <input type="hidden" name="action" value="receive.jsp" /> <br>var url = $("input[name='action']").val(); <br>// 2. 也可以直接用某个dom对象的属性来获取 <br>// <input id="imageaction" type="hidden" action="receive.jsp"> <br>// var url = $("#imageaction").attr("action"); <br>// 因为是string,所以服务器需要对数据进行转码,写文件操作等. <br>// 个人约定,所有http参数名字全部小写 <br>console.log(dataurl); <br>//console.log(imagedata); <br>var data = { <br>imagename: "myImage.png", <br>imagedata: imagedata <br>}; <br>jQuery.ajax( { <br>url : url, <br>data : data, <br>type : "POST", <br>// 期待的返回值类型 <br>dataType: "json", <br>complete : function(xhr,result) { <br>//console.log(xhr.responseText); <br>var $tip2 = $("#tip2"); <br>$tip2.text('网络连接失败!'); <br>return false; <br>} <br>var text = xhr.responseText; <br>$tip2 .text('网络错误!'); <br>return false; <br>} <br>var json = eval("(" text ")"); tip2.text('解析错误!'); <br>return false; <br>} else { <br>$tip2.text(json.message); <br>//console.dir(json ); <br>//console.log(xhr.responseText) <br>}); <br>}; <br>function init(){ <br>// 获取DOM元素对象 <br>var target = document.getElementById("drop-target"); <br>// Dragover-Ereigniszustellung (über DOM-Element ziehen) verhindern <br>target.addEventListener("dragover", function(e){e.preventDefault( ) ;}, true); <br>// Ziehen Sie das Mausereignis und lassen Sie es los<br>target.addEventListener("drop", function(e){ <br>// Verhindern Sie Standardereignisse und Ereignisweitergabe<br>e.preventDefault (); <br>// Rufen Sie die vorherige Ladebildfunktion auf, der Parameter ist die erste Datei des dataTransfer-Objekts <br>loadImage(e.dataTransfer.files[0]}, true) ; >var setheight = document.getElementById("setheight"); <br>var maxheight = document.getElementById("maxheight"); <br>setheight.addEventListener("click", function(e){ <br> // <br>var value = maxheight.value; <br>if(/^d $/.test(value)){ <br>MAX_HEIGHT = parseInt(value); <br>e.preventDefault( ); 🎜>},true); <br>var btnsend = document.getElementById("btnsend"); <br>btnsend.addEventListener("click", function(e){ <br>// <br>sendImage (); <br>},true); <br>window.addEventListener("DOMContentLoaded", function() { <br>// <br>init(); <br>},false) ; ></script>
>

Ziehen Sie ein Foto aus dem Ordner in das Feld unten, die Leinwand und JavaScript werden automatisch skaliert.

maxheight" value="100"/>


Ziehen Sie die Bilddatei hierher...
id="preview" style="background:#f4f4f4;width:400px;height:200px;min-height:100px;min-width:200px;">< ;canvas id="myCanvas">< ;/canvas>

Serverseite, require.jsp





Code kopieren


Code Wie folgt:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="sun.misc.BASE64Decoder"%>
<%@page import="java.io.*"%>
<%@page import="org.springframework.web.util.UriComponents"%>
<%@page import="java.net.URLDecoder"%>
<% !
// 本文件:/receive.jsp
// 图片存放路径
String photoPath = "D:/blog/upload/photo/";
Fichier photoPathFile = new File(photoPath);
// références : http://blog.csdn.net/remote_roamer/article/details/2979822
private boolean saveImageToDisk(byte[] data,String imageName) throws IOException{
int len ​​= data. longueur;
//
// 写入到文件
FileOutputStream outputStream = new FileOutputStream(new File(photoPathFile,imageName));
outputStream.write(data);
outputStream.flush();
outputStream.close();
//
retour vrai ;
}
private byte[] decode(String imageData) throws IOException{
BASE64Decoder decoder = new BASE64Decoder();
byte[] data = decoder.decodeBuffer(imageData);
for(int i=0;i{
if(data[i]<0)
{
//调整异常数据
données[i] =256 ;
}
}
//
retourner les données ;
}
%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() "://" request.getServerName() ":" request.getServerPort() chemin "/";
%>
<%
//如果是IE,那么需要设置为text/html,否则会弹框下载
//response.setContentType("text/html;charset=UTF-8");
response.setContentType("application/json;charset=UTF-8");
//
String imageName = request.getParameter("imagename");
String imageData = request.getParameter("imagedata");
int succès = 0 ;
Chaîne message = "";
if(null == imageData || imageData.length() < 100){
// 数据太短,明显不合理
message = "上传失败,数据太短或不存在";
} else {
// 去除开头不合理的数据
imageData = imageData.substring(30);
imageData = URLDecoder.decode(imageData,"UTF-8");
//System.out.println(imageData);
byte[] data = decode(imageData);
int len ​​= data.length;
int len2 = imageData.length();
if(null == imageName || imageName.length() < 1){
imageName = System.currentTimeMillis() ".png";
}
saveImageToDisk(data,imageName);
//
succès = 1 ;
message = "上传成功,参数长度:" len2 "字符,解析文件大小:" len "字节";
}
// 后台打印
System.out.println("message=" message);
%>
{
"message": "<%=message %>",
"succès": <%=succès %>
}
Verwandte Etiketten:
Quelle:php.cn
Vorheriger Artikel:Verwenden Sie eine HTML5-Datei, um base64 in images_html5-Tutorial-Fähigkeiten zu konvertieren Nächster Artikel:Einführung in die Verwendung der neuen HTML5-Formularelemente (Datenliste/Keygen/Ausgabe)_HTML5-Tutorialfähigkeiten
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
Neueste Artikel des Autors
Aktuelle Ausgaben
verwandte Themen
Mehr>
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage