Maison > interface Web > Tutoriel H5 > le corps du texte

Exemple complet de zoom et de téléchargement d'images via les compétences du didacticiel Canvas et File API_html5

WBOY
Libérer: 2016-05-16 15:49:07
original
1542 Les gens l'ont consulté

Exemple d'adresse : Démo de redimensionnement de toile
Auteur original : Dr Tom Trenka
Date originale : 6 août 2013
Date de traduction : 8 août 2013

Tom Trenka C'est un immense honneur pour moi d'écrire un article pour « mon » blog. Tom a été l'un des premiers contributeurs au framework Dojo et a été mon mentor chez SitePen. J'ai été témoin de son génie au plus haut niveau, et il a toujours été le premier à prévoir de nombreux problèmes difficiles avec des solutions tournées vers l'avenir. Il pense toujours de l'extérieur et résout les problèmes marginaux de manière non conventionnelle mais solide. Cet article en est un parfait exemple.
Dernièrement, on m'a beaucoup demandé comment créer une API d'interface utilisateur qui permettrait aux utilisateurs de télécharger des images sur un serveur (entre autres choses) et d'être utilisée côté client du grand nombre de sites Web pris en charge par notre société. Habituellement, c'est une chose très simple : créez un formulaire, ajoutez une zone de saisie de type de fichier, laissez l'utilisateur sélectionner une image sur l'ordinateur et définissez le formulaire enctype="multipart/form-data" sur les propriétés de la balise de formulaire, puis téléchargez-le. . Assez simple, n'est-ce pas ? En fait, voici un exemple assez simple : Cliquez pour entrer
Mais que se passe-t-il si vous souhaitez prétraiter l'image d'une manière ou d'une autre avant de la télécharger ? Par exemple, vous devez d'abord compresser la taille de l'image, ou vous avez besoin que l'image soit uniquement dans certains types de formats, tels que png ou jpg, que devez-vous faire ?
Utilisez Canvas pour le résoudre !

Introduction à Canvas
Canvas est un nouvel élément DOM en HTML5 qui permet aux utilisateurs de dessiner des graphiques directement sur la page, généralement en utilisant JavaScript. Les différentes normes de format sont également différentes. Par exemple, SVG est une API raster (API raster) tandis que VML est une API vectorielle. Vous pouvez envisager d'utiliser Adobe Illustrator (vecteur) pour le dessin et Adobe Photoshop (raster) pour le dessin.

Ce que vous pouvez faire sur Canvas, c'est lire et restituer des images, et vous permettre de manipuler les données d'image via JavaScript. Il existe de nombreux articles qui présentent pour vous le traitement d'image de base - en se concentrant principalement sur diverses techniques de filtrage d'image - mais tout ce dont nous avons besoin est de redimensionner l'image et de la convertir dans un format de fichier spécifique, et Canvas peut faire ces choses complètement.

Nos exigences supposées, telles que la hauteur de l'image ne dépassant pas 100 pixels, quelle que soit la hauteur de l'image originale. Le code de base est le suivant :

Copiez le code
Le code est le suivant :

// Paramètres, hauteur maximale
var MAX_HEIGHT = 100;
// Rendu
function render(src){
// Créer un objet Image
var image = new Image() ;
// Lier le gestionnaire d'événement de chargement et l'exécuter une fois le chargement terminé
image.onload = function(){
// Récupérer l'objet DOM canevas
var canvas = document.getElementById("myCanvas ");
// Si la hauteur dépasse la norme
if(image.height > MAX_HEIGHT) {
// Mise à l'échelle proportionnelle à la largeur *=
image.width *= MAX_HEIGHT / image.height ;
image.height = MAX_HEIGHT;
}
// Récupère l'objet environnement 2d de Canvas,
// On peut comprendre que Context est l'administrateur et Canvas est la maison
var ctx = canvas.getContext("2d");
//Effacer l'écran du canevas
ctx.clearRect(0, 0, canvas.width, canvas.height);
//Réinitialiser la largeur et la hauteur du canevas
canvas.width = image.width;
canvas.height = image.height;
// Dessinez l'image sur la toile
ctx.drawImage(image, 0, 0, image.width, image .height);
// !!! Notez que l'image n'est pas ajoutée au dom
};
// Définissez l'attribut src et le navigateur le chargera automatiquement.
// N'oubliez pas que l'événement doit d'abord être lié avant que l'attribut src puisse être défini, sinon des problèmes de synchronisation se produiront.
image.src = src;
}

Dans l'exemple ci-dessus, vous pouvez utiliser la méthode toDataURL() de Canvas pour obtenir la valeur codée en Base64 de l'image (qui peut être également comprise comme une chaîne hexadécimale ou un flux de données binaires
Remarque : toDataURL de Canvas). () L'URL obtenue commence par une chaîne et contient 22 données inutiles "data:image/png;base64", qui doivent être filtrées sur le client ou le serveur
En principe, tant que le navigateur le prend en charge, le. Adresse URL Il n'y a pas de limite de longueur et la limite de longueur de 1 024 est unique à l'ancienne génération d'IE.

Excusez-moi, comment obtenir les images dont nous avons besoin ?
Bon garçon, je suis content que tu aies demandé. Vous ne pouvez pas le traiter directement via la zone de saisie du fichier. Tout ce que vous pouvez obtenir de cet élément de la zone de saisie du fichier est uniquement le chemin d'accès au fichier sélectionné par l'utilisateur. Selon l'imagination conventionnelle, vous pouvez charger des images via ces informations de chemin, mais cela est irréaliste dans le navigateur. (Note du traducteur : les fabricants de navigateurs doivent s'assurer que leurs navigateurs sont absolument sécurisés afin de gagner des parts de marché, au moins pour éviter les attaques médiatiques. Si cela est autorisé, des URL malveillantes peuvent tenter d'obtenir certaines informations sensibles en regroupant les chemins de fichiers Afin de répondre à cette exigence, nous pouvons utiliser l'API File de HTML5 pour lire les fichiers sur le disque de l'utilisateur et utiliser ce fichier comme source de l'image (src, source


Introduction à l'API File). La nouvelle interface File API est un moyen de lire et de répertorier les répertoires de fichiers utilisateur sans enfreindre les règles de sécurité du bac à sable - grâce aux restrictions du bac à sable, les sites Web malveillants ne peuvent pas écrire de virus sur les disques utilisateur, bien sûr, ils ne peuvent pas être exécutés.
L'objet de lecture de fichiers que nous souhaitons utiliser s'appelle FileReader. FileReader permet aux développeurs de lire le contenu des fichiers (l'implémentation de navigateurs spécifiques peut être très différente).

En supposant que nous avons obtenu le chemin du fichier image, puis en nous appuyant sur le code précédent, il devient facile d'utiliser FileReader pour charger et restituer l'image :


Copier le codeLe code est le suivant :
// Charger le fichier image (chemin url)
fonction loadImage(src) {
/ / Filtrer les fichiers non-image
if(!src.type.match(/image.*/)){
if(window.console){
console.log( "Type de fichier sélectionné Pas une image : ", src.type);
} else {
window.confirm("Seuls les fichiers image peuvent être sélectionnés");
}
return; }
// Créez un objet FileReader et appelez la fonction de rendu pour terminer le rendu
var reader = new FileReader();
// Lier la fonction de rappel automatique de l'événement de chargement
reader.onload = function (e){
/ / Appeler la fonction de rendu précédente
render(e.target.result
}
// Lire le contenu du fichier
reader.readAsDataURL(src);
};


Excusez-moi, comment obtenir le fichier ?
Petit lapin blanc, sois patient ! Notre prochaine étape consiste à obtenir le fichier, et bien sûr, il existe de nombreuses façons de le faire. Par exemple : vous pouvez utiliser une zone de texte pour permettre aux utilisateurs de saisir des chemins de fichiers, mais évidemment la plupart des utilisateurs ne sont pas des développeurs et n'ont aucune idée des valeurs à saisir
Pour plus de commodité, nous utilisons l'interface API Drag and Drop. .


Utilisation de l'API Drag and Drop
L'interface glisser-déposer (Drag and Drop) est très simple - sur la plupart des éléments DOM, vous pouvez lier les gestionnaires d'événements à l'implémentation tant que vous le faites. lorsque l'utilisateur fait glisser un fichier du disque vers l'objet dom et relâche la souris, nous pouvons lire le fichier. Le code est le suivant :


Copier le code Le code est le suivant :
function init(){
// Récupérer l'objet élément DOM
var target = document.getElementById("drop-target");
// Empêcher la livraison de l'événement par glisser-déplacer au-dessus de l'élément DOM
target.addEventListener("dragover ", function(e){e.preventDefault();}, true);
// Faites glisser et relâchez l'événement de la souris
target.addEventListener("drop", function(e ){
// Empêcher les événements par défaut et la propagation des événements
e.preventDefault();
// Appeler la fonction de chargement d'image précédente, le paramètre est le premier fichier de l'objet dataTransfer
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();
},true);
var btnsend = document.getElementById("btnsend"); ", function(e ){
//
sendImage();
},true);
};


Nous pouvons également effectuer d'autres traitements, comme l'affichage d'images d'aperçu. Mais si vous ne souhaitez pas compresser l’image, cela ne sert probablement à rien. Nous utiliserons Ajax pour télécharger des données d'image via la méthode de publication HTTP. L'exemple suivant utilise le framework Dojo pour compléter la requête. Bien entendu, vous pouvez également utiliser d'autres technologies Ajax pour l'implémenter
Le code Dojo est le suivant :

. Copier le code
Le code est le suivant :

// Le traducteur ne comprend pas Dojo, donc l'implémentation de jQuery sera jointe plus tard
/ / N'oubliez pas que DTK 1.7 est AMD !
require(["dojo/request"], function(request){
// Définissez l'URL de la requête, les paramètres et les rappels.
request.post("image -handler.php", {
data : {
imageName : "myImage.png",
imageData: encodeURIComponent(document.getElementById("canvas").toDataURL("image/png"))
}
} .then(function(text){
console.log("Le serveur a renvoyé : ", text);
});

jQuery est implémenté comme suit :



Copier le codeLe code est le suivant :
// Télécharger l'image, version jQuery
function sendImage(){
// Récupérer l'objet DOM canevas
var canvas = document.getElementById("myCanvas"); les données d'image codées en Base64, le format est une chaîne
// Au début de "data:image/png;base64", il doit être supprimé côté client ou serveur, et les parties suivantes peuvent être écrites directement dans le fichier.
var dataurl = canvas.toDataURL("image/png");
// Encoder l'URI pour la sécurité
// data:image/png;base64, commençant
var imagedata = encodeURIComponent( dataurl) ;
//var url = $("#form").attr("action");
// 1. Si le formulaire est difficile à traiter, vous pouvez utiliser un champ caché pour définir la demande. Adresse
//
var url = $("input[name='action']").val ();
// 2. Vous pouvez également utiliser directement les attributs d'un objet DOM pour obtenir
//
// var url = $("#imageaction").attr("action");
// Comme il s'agit d'une chaîne, le serveur doit transcoder les données, écrire des opérations sur les fichiers, etc.
// Accord personnel, tous les noms de paramètres http sont en minuscules
console.log(dataurl);
//console.log(imagedata); monImage .png",
imagedata: imagedata
};
jQuery.ajax( {
url : url,
data : data,
type : "POST",
// Type de valeur de retour attendue
dataType : "json",
complete : function(xhr,result) {
//console.log(xhr.responseText
var $tip2 = $( "#tip2");
if(!xhr){
$tip2.text('La connexion réseau a échoué !');
return false
}
var text = xhr.responseText; ;
if(!text){
$tip2.text('Erreur réseau !');
return false
}
var json = eval("("text ")" );
if(!json){
$tip2.text('Erreur d'analyse !');
return false
} else {
$tip2.text(json.message) ;
}
//console.dir(json);
//console.log(xhr.responseText);
}
}; 🎜>
OK, c'est fait ! Tout ce que vous avez à faire est de créer une interface utilisateur simple qui vous permet de contrôler la taille de l'image. Les données téléchargées sur le serveur n'ont pas besoin de gérer le type d'enc de multi-part/form-data. Un simple gestionnaire de formulaire POST suffit
D'accord, voici un exemple de code complet :

<.>


Copier le code


Le code est le suivant :

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



通过Canvas et 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.hauteur = MAX_HEIGHT ; <br>} <br>// 获取 canvas的 2d 环境对象, <br>// 可以理解Context是管理员,canvas是房子 <br>var ctx = canvas.getContext("2d"); <br>// canvas清屏 <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>// 记住必须先绑定事件,才能设置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>retour; <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 dans <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. Le formulaire de formulaire est caché, et le formulaire est caché <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; .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>} ; <br>function init(){ <br>// 获取DOM元素对象 <br>var target = document.getElementById("drop-target"); <br>// Empêcher la livraison de l'événement par glissement (glisser au-dessus de l'élément DOM) <br>target.addEventListener("dragover", function(e){e.preventDefault( ) ;}, true); <br>// Faites glisser et relâchez l'événement de la souris<br>target.addEventListener("drop", function(e){ <br>// Empêchez les événements par défaut et la propagation des événements<br>e.preventDefault (); <br>// Appelez la fonction de chargement d'image précédente, le paramètre est le premier fichier de l'objet dataTransfer <br>loadImage(e.dataTransfer.files[0] <br>}, 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); 🎜>},true); <br>var btnsend = document.getElementById("btnsend"); <br>btnsend.addEventListener("click", function(e){ <br>// <br>sendImage (); <br>},true); <br>}; <br>window.addEventListener("DOMContentLoaded", function() { <br>// <br>init(); <br>},false) ; ></script>



Zoomez et téléchargez des images via l'API Canvas et File >

Faites glisser une photo du dossier dans la zone ci-dessous, le canevas et JavaScript seront automatiquement mis à l'échelle.


maxheight" value="100"/>



:400px;height:200px;min-height:100px;min-width:200px;background:#eee;cursor:pointer;">Faites glisser le fichier image ici...




id="preview" style="background:#f4f4f4;width:400px;height:200px;min-height:100px;min-width:200px;"< ;/toile>



Page du serveur, recevoir.jsp





Copier le code


code Comme suit :






// 本檔案:/receive.jsp
// 圖片貨架
String photoPath = "D:/blog/upload/photo/";
檔案photoPathFile = new File(photoPath);
// 參考資料:http://blog.csdn.net/remote_roamer/article/details/2979822
private boolean saveImageToDisk(byte[] data,String imageName) throws IOException{Disk(byte[] data,String imageName) throws IOException{ //
// 寫入到檔案
FileOutputStream outputStream = new FileOutputStream(new File(photoPathFile,imageName));
outputStream.write(資料);
outputStream. ();
outputStream.close();
//
回傳true;
}
私有byte[] 解碼(String imageData)拋出IOException{
BASE64Decoder 解碼器= new BASE64Decoder();
byte[] data = detector.decodeBuffer(imageData);
for(int i=0;i{
if(data[i ]{
//調整異常資料
資料[i]=256;
}
}
//
回傳資料;
}
%>
字串路徑= request.getContextPath();
String basePath = request.getScheme() "://" request.getServerName() ":" request.getServerPort( ) 路徑"/";
%>
//如果是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 成功= 0;
字串訊息= "";
if(null == imageData || imageData.length() //資料太短,不合理
message = "上傳失敗,資料太短明顯或不存在";
} else {
//取出初始化不穩定的資料
imageData = imageData.substring(30);
imageData = URLDecoder.decode(imageData,"UTF-8");
//System.out.println(imageData);
byte[] 資料= 解碼(imageData);
int len = data.length;
int len2 = imageData.length();
if(null == imageName || imageName.length() imageName = System.currentTimeMillis() ".png";
}
saveImageToDisk(data,imageName);
//
成功= 1;
message = "上傳成功,參數長度:" len2 "字符,解析檔案大小:" len "位元組";
}
//後台列印
System.out.println("message=" message);
%>
{
"訊息": "",
"成功": ;
}

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal