Rumah >hujung hadapan web >Tutorial H5 >Contoh lengkap mengezum dan memuat naik imej melalui kemahiran tutorial Kanvas dan Fail API_html5

Contoh lengkap mengezum dan memuat naik imej melalui kemahiran tutorial Kanvas dan Fail API_html5

WBOY
WBOYasal
2016-05-16 15:49:071592semak imbas

Contoh alamat: Demo Ubah Saiz Kanvas
Pengarang asal: Dr. Tom Trenka
Tarikh asal: 6 Ogos 2013
Tarikh terjemahan: 8 Ogos 2013

Tom Trenka Ia adalah satu penghormatan besar bagi saya untuk menulis artikel untuk blog "saya". Tom ialah salah seorang penyumbang asal kepada rangka kerja Dojo dan merupakan mentor saya di SitePen. Saya menyaksikan kejeniusannya di peringkat tertinggi, dan dia sentiasa menjadi orang pertama yang meramalkan banyak masalah sukar dengan penyelesaian yang berpandangan ke hadapan. Dia sentiasa berfikir dari luar dan menyelesaikan masalah sampingan dengan cara yang tidak konvensional tetapi kukuh. Artikel ini adalah contoh yang sempurna.
Akhir-akhir ini saya banyak ditanya tentang mencipta API antara muka pengguna yang akan membolehkan pengguna memuat naik imej ke pelayan (antara lain) dan digunakan pada bahagian pelanggan bagi sejumlah besar tapak web yang disokong oleh syarikat kami. Biasanya ini adalah perkara yang sangat mudah - buat borang, tambah kotak input jenis fail, biarkan pengguna memilih imej dari komputer, dan tetapkan borang enctype="multipart/form-data" pada sifat teg borang dan kemudian muat naik . Cukup mudah, bukan? Sebenarnya, berikut adalah contoh yang cukup mudah; Klik untuk masuk
Tetapi bagaimana jika anda ingin mempraproses imej dalam beberapa cara sebelum memuat naiknya? Sebagai contoh, anda mesti memampatkan saiz imej dahulu, atau anda memerlukan imej hanya dalam jenis format tertentu, seperti png atau jpg, apakah yang perlu anda lakukan?
Gunakan kanvas untuk menyelesaikannya!

Pengenalan kepada Kanvas
Kanvas ialah elemen DOM baharu dalam HTML5 yang membolehkan pengguna melukis grafik terus pada halaman, biasanya menggunakan JavaScript. Piawaian format yang berbeza juga berbeza Sebagai contoh, SVG ialah API raster (API raster) manakala VML ialah API vektor Anda boleh mempertimbangkan untuk menggunakan Adobe Illustrator (vektor) untuk melukis dan Adobe Photoshop (raster) untuk melukis.

Apa yang boleh anda lakukan di atas kanvas ialah membaca dan memaparkan imej serta membenarkan anda memanipulasi data imej melalui JavaScript. Terdapat banyak artikel sedia ada yang menunjukkan pemprosesan imej asas untuk anda - memfokus terutamanya pada pelbagai teknik penapisan imej - tetapi apa yang kita perlukan ialah menskala imej dan menukarnya kepada format fail tertentu, dan Canvas boleh melakukan perkara ini sepenuhnya.

Keperluan yang diandaikan kami, seperti ketinggian imej tidak melebihi 100 piksel, tidak kira berapa tinggi imej asal. Kod asas adalah seperti berikut:

Salin kod
Kod adalah seperti berikut:

// Parameter, ketinggian maksimum
var MAX_HEIGHT = 100;
// Rendering
function render(src){
// Cipta objek Imej
var image = new Image() ;
// Ikat pengendali acara muat dan laksanakan selepas pemuatan selesai
image.onload = function(){
// Dapatkan objek DOM kanvas
var canvas = document.getElementById("myCanvas ");
// Jika ketinggian melebihi standard
jika(imej.tinggi > MAX_HEIGHT) {
// Skala berkadar lebar *=
imej.lebar *= MAX_HEIGHT / imej.tinggi ;
image.height = MAX_HEIGHT;
}
// Dapatkan objek persekitaran 2d kanvas,
// Dapat difahami bahawa Konteks ialah pentadbir dan kanvas ialah rumah
var ctx = canvas.getContext("2d");
//Kosongkan skrin kanvas
ctx.clearRect(0, 0, canvas.width, canvas.height
//Tetapkan semula lebar dan tinggi kanvas
canvas.width = image.width;
canvas.height = image.height;
// Lukiskan imej ke atas kanvas
ctx.drawImage(imej, 0, 0, image.width, imej .height);
// !!! Ambil perhatian bahawa imej tidak ditambahkan pada dom
};
// Ingat bahawa acara mesti diikat terlebih dahulu sebelum atribut src boleh ditetapkan, jika tidak masalah penyegerakan akan berlaku.
imej.src = src;
};
Dalam contoh di atas, anda boleh menggunakan kaedah toDataURL() canvas untuk mendapatkan nilai imej yang dikodkan Base64 (yang boleh juga difahami sebagai rentetan perenambelasan atau strim data binari
Nota: toDataURL kanvas). () URL yang diperolehi bermula dengan rentetan dan mempunyai 22 data yang tidak berguna "data:image/png;base64," yang perlu ditapis pada klien atau pelayan
Selagi pelayar menyokongnya Alamat URL Tiada had untuk panjang, dan had panjang 1024 adalah unik untuk generasi lama IE.

Maaf, bagaimana untuk mendapatkan imej yang kami perlukan?
Anak baik, saya gembira anda bertanya. Anda tidak boleh memprosesnya terus melalui kotak input Fail Apa yang anda boleh dapatkan daripada elemen kotak input fail ini hanyalah laluan ke fail yang dipilih oleh pengguna. Mengikut imaginasi konvensional, anda boleh memuatkan imej melalui maklumat laluan laluan ini, tetapi ini tidak realistik dalam penyemak imbas. (Nota penterjemah: Pengeluar penyemak imbas mesti memastikan penyemak imbas mereka benar-benar selamat untuk mendapatkan bahagian pasaran dan sekurang-kurangnya mengelakkan serangan media. Jika ini dibenarkan, URL berniat jahat boleh cuba mendapatkan maklumat sensitif tertentu dengan menggabungkan laluan fail). >Untuk mencapai keperluan ini, kami boleh menggunakan API Fail HTML5 untuk membaca fail pada cakera pengguna dan menggunakan fail ini sebagai sumber imej (src, sumber


Pengenalan API Fail Antara muka File API baharu ialah cara untuk membaca dan menyenaraikan direktori fail pengguna tanpa melanggar sebarang peraturan kotak pasir keselamatan - melalui sekatan kotak pasir, tapak web berniat jahat tidak boleh menulis virus, sudah tentu, tidak boleh dilaksanakan. Objek pembacaan fail yang ingin kami gunakan dipanggil FileReader FileReader membenarkan pembangun membaca kandungan fail (pelaksanaan penyemak imbas tertentu mungkin sangat berbeza).

Dengan mengandaikan bahawa kami telah memperoleh laluan laluan fail imej, kemudian bergantung pada kod sebelumnya, menjadi mudah untuk menggunakan FileReader untuk memuatkan dan memaparkan imej:



Salin kodKod adalah seperti berikut:
// Muatkan fail imej (laluan url)
function loadImage(src) {
/ / Tapis fail bukan jenis imej
if(!src.type.match(/image.*/)){
if(window.console){
console.log( "Jenis fail yang dipilih Bukan gambar: ", src.type);
} else {
window.confirm("Hanya fail gambar boleh dipilih"); }
// Cipta objek FileReader dan panggil fungsi render untuk melengkapkan rendering
var reader = new FileReader(); (e){
/ / Panggil fungsi render sebelumnya
render(e.target.result);
// Baca kandungan fail
reader.readAsDataURL(src);
};


Maaf, bagaimana untuk mendapatkan fail?
Arnab putih kecil, bersabarlah! Langkah seterusnya kami adalah untuk mendapatkan fail, dan sudah tentu terdapat banyak cara untuk melakukan ini. Sebagai contoh: anda boleh menggunakan kotak teks untuk membenarkan pengguna memasuki laluan fail, tetapi jelas kebanyakan pengguna bukan pembangun dan tidak tahu nilai apa yang hendak dimasukkan
Untuk kemudahan pengguna, kami menggunakan antara muka API Seret dan Lepas .


Menggunakan API Drag and Drop
Antara muka seret dan lepas (Seret dan Lepas) adalah sangat mudah - pada kebanyakan elemen DOM, anda boleh mengikat pengendali acara kepada Pelaksanaan apabila pengguna menyeret fail dari cakera ke objek dom dan melepaskan tetikus, kita boleh membaca fail tersebut. Kodnya adalah seperti berikut:




Salin kod

Kod adalah seperti berikut:
function init(){ // Dapatkan objek elemen DOM var target = document.getElementById("drop-target"); // Cegah dragover (seret di atas elemen DOM) penghantaran acara target.addEventListener("dragover ", function(e){e.preventDefault();}, true);
// Seret dan lepaskan acara tetikus
target.addEventListener("drop", function(e); ){
// Cegah peristiwa lalai dan penyebaran peristiwa
e.preventDefault();// Panggil fungsi imej muat sebelumnya, parameter ialah fail pertama bagi objek Pemindahan data
loadImage(e .dataTransfer.files[ 0]);
}, true);
var setheight = document.getElementById("setheight"); setheight.addEventListener("klik", fungsi(e){
//
nilai var = maxheight.value;
if(/^d $/.test(value)){
MAX_HEIGHT = parseInt(nilai);
}
e.preventDefault();
},true); var btnsend = document.getElementById("btnsend"); ", fungsi(e ){
//
hantarImej();
},benar);
};


Kami juga boleh melakukan beberapa pemprosesan lain, seperti memaparkan imej pratonton. Tetapi jika anda tidak mahu memampatkan imej, ia mungkin tidak berguna. Kami akan menggunakan Ajax untuk memuat naik data imej melalui kaedah pos HTTP. Contoh berikut menggunakan rangka kerja Dojo untuk melengkapkan permintaan Sudah tentu, anda juga boleh menggunakan teknologi Ajax lain untuk melaksanakannya
Kod Dojo adalah seperti berikut:

Salin Kod
Kod tersebut adalah seperti berikut:

// Penterjemah tidak memahami Dojo, jadi pelaksanaan jQuery akan dilampirkan kemudian
/ / Ingat bahawa DTK 1.7 ialah AMD
require(["dojo/request"], function(request){
// Tetapkan URL permintaan, parameter dan panggilan balik.
request.post("image -handler.php", {
data: {
imageName: "myImage.png",
imageData: encodeURIComponent(document.getElementById("canvas").toDataURL("image/png"))
}
} ).then(function(text){
console.log("Pelayan dikembalikan: ", teks);
}); >
jQuery dilaksanakan seperti berikut :



Salin kod
Kod adalah seperti berikut:
// Muat naik imej, versi jQuery
fungsi sendImage(){
// Dapatkan objek DOM kanvas
var canvas = document.getElementById("myCanvas"); data imej yang dikodkan Base64, formatnya ialah rentetan
// Pada permulaan "data:image/png;base64,", ia perlu dialih keluar pada sisi klien atau pelayan, dan bahagian berikut boleh ditulis terus ke fail.
var dataurl = canvas.toDataURL("image/png");
// Encode URI untuk keselamatan
// data:image/png;base64, starting
var imagedata = encodeURIComponent( dataurl) ;
//var url = $("#form").attr("action"); Alamat
//
var url = $("input[name='action']").val ();
// 2. Anda juga boleh terus menggunakan atribut objek DOM untuk mendapatkan
//
// var url = $("#imageaction").attr("action");
// Perjanjian peribadi, semua nama parameter http adalah dalam huruf kecil
console.log(dataurl
//console.log(imagedata =
nama imej: "); myImage .png",
imagedata: imagedata
};
jQuery.ajax( {
url : url,
data : data,
type : "POST",
// Jenis nilai pulangan yang dijangkakan
dataType: "json",
complete : function(xhr,result) {
//console.log(xhr.responseText) var $tip2 = $(); "#tip2");
if(!xhr){
$tip2.text('Sambungan rangkaian gagal!');
return false; ;
if(!text){
$tip2.text('Ralat rangkaian!');
kembali palsu; );
jika(!json){
$tip2.text('Parse error!');
return false; ;
}
//console.dir(json>//console.log(xhr.responseText}
}); 🎜>
OK, selesai! Apa yang anda perlu lakukan ialah mencipta antara muka pengguna ringkas yang membolehkan anda mengawal saiz imej. Data yang dimuat naik ke pelayan tidak perlu mengendalikan enctype bagi multi-part/form-data cukup sekadar pengendali borang POST
Baiklah, berikut adalah contoh kod lengkap:





Salin kod


Kod adalah seperti berikut:

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



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







// 参数,最大高度
var MAX_HEIGHT = 100;
// 渲染
fungsi render(src){
// 创建一个 Imej 对象
var image = new Image();
// 绑定 memuatkan 事件处理器,加载完成后执行
image.onload = function(){
// 获取 canvas DOM 对象 var.my ") ;
// 如果高度超标
jika(imej.tinggi > MAX_HEIGHT) {
// 宽度等比例缩放 *=
imej.lebar;*= MAX.tinggi
imej.tinggi = MAX_HEIGHT;
}
// 获取 canvas的 2d 环境对象,
// 可以理解Context是管理员,canvas是房子 2d ."Context s"(d🎜 =>var.
// canvas清屏
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 重置canvas宽高
canvas.width = image.width;
canvas.height = imej.height;
// 将图像绘制到kanvas上
ctx.drawImage(imej, 0, 0, image.width, image.height);
// !!! 注意,imej 没有加入到 dom之中
};
// 设置src属性,浏览器会自动加载。
// 记住必须先绑定事件,才能记住必须先绑定事件,才能记住必须先绑定事件,才能记亮步问题。
image.src = src;
};
// 加载 图像文件(url路径)
function loadImage(src){
// 过滤掉 非 image 类型的文件
if.(*match. )){
if(window.console){
console.log("选择的文件类型不是图片: ", src.type);
} lain {
window.confirm("只能选择图片文件");
}
kembali;
}
// 创建 FileReader 对象 并调用 render 函数来完成渲染.
var reader = new FileReader();
// 绑定load事件自动回调函数
reader.onload = function(e){
// 调用前面的 render 函数
render(e.target);
};
// 读取文件内容
reader.readAsDataURL(src);
};
// 上传图片,jQuery版
function sendImage(){
// 获取 canvas DOM 对象
var canvas = document.getElementById("myCanvas");
// 获取Base64编码后的图像数据,格式是字符串
// "data:imej/png;base64,"开头,需字符串
// "data:image/png;base64,"开头,需字符串将其去掉,后面的部分可以直接写入文件。
var dataurl = canvas.toDataURL("image/png");
// 为安全 对URI进行编码
// data:image/png;base64, 开头
var imagedata = encodeURIComponent(dataurl);
//var url = $("#form").attr("action");
// 1. 如果form表单不好处理,可以使用某个hidden隐藏域来设置请求处理,可以使用某个hidden隐藏域来设置请求地址 var url = $("input[name='action']").val();
// 2. 也可以直接用某个dom对象的属性来获取
// // var url = $("#imageaction").attr("action");
// 因为是string,所以服务器需要对数据进行转码,写文件操作等。
//http 个小物全部小写
console.log(dataurl);
//console.log(data imej);
data var = {
nama imej: "myImage.png",
data imej: imagedata
};
jQuery.ajax( {
url : url,
data : data,
jenis : "POST",
// 期待的返回值类型
dataType: "json",
lengkap : fungsi(xhr,hasil) {
//console.log(xhr.responseText);
var $tip2 = $("#tip2");
$tip2.text('网络连接失败!');
kembali palsu;
}
var text = xhr.responseText; .text('网络错误!');
kembali false;
}
var json = eval("(" text ")"); tip2.text('解析错误!');
return false;
} else {
$tip2.text(json.message); );
//console.log(xhr.responseText
}
});
};
fungsi init(){
// 获取DOM元素对象
var target = document.getElementById("drop-target");
// Cegah dragover (seret di atas elemen DOM) penghantaran acara
target.addEventListener("dragover", function(e){e.preventDefault( ) ;}, benar);
// Seret dan lepaskan acara tetikus
target.addEventListener("drop", function(e){
// Cegah peristiwa lalai dan penyebaran acara
e.preventDefault ();
// Panggil fungsi muatkan imej sebelumnya, parameter adalah fail pertama bagi objek Pemindahan data
loadImage(e.dataTransfer.files[0]), benar) ; >var setheight = document.getElementById("setheight");
var maxheight = document.getElementById("maxheight"); 🎜>nilai var = maxheight.value;
if(/^d $/.test(value)){
MAX_HEIGHT = parseInt(value); 🎜>},true);
var btnsend = document.getElementById("btnsend");
},benar);
};
window.addEventListener("DOMContentLoaded", function() {
//
init();
},false) ; >


>

Seret foto dari folder ke dalam kotak di bawah, kanvas dan JavaScript akan berskala secara automatik.


maxheight" value="100"/>




Seret fail imej ke sini...


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


Halaman pelayan, receive.jsp





Salin kod


kod Seperti berikut:

<%@ 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/";
File photoPathFile = new File(photoPath);
// Referenzen: http://blog.csdn.net/remote_roamer/article/details/2979822
private boolean saveImageToDisk(byte[] data,String imageName) throws IOException{
int len ​​= data. Länge;
//
// 写入到文件
FileOutputStream outputStream = new FileOutputStream(new File(photoPathFile,imageName));
outputStream.write(data);
outputStream.flush();
outputStream.close();
//
return true;
}
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)
{
//调整异常数据
Daten[i] =256;
}
}
//
Rückgabedaten;
}
%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() "://" request.getServerName() ":" request.getServerPort() path "/";
%>
<%
//如果是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 success = 0;
String 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);
//
Erfolg = 1;
message = "Beispielsweise:" len2 "Beispiel:" len "Beispiel";
}
// 后台打印
System.out.println("message=" message);
%>
{
"message": "<%=message %>",
"success": <%=success %>
}
Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn