通过Canvas及File API缩放并上传图片完整示例

  1 <!DOCTYPE html> 
  2 <html> 
  3 <head> 
  4 <title>通过Canvas及File API缩放并上传图片</title> 
  5 <meta http-equiv="pragma" content="no-cache"> 
  6 <meta http-equiv="cache-control" content="no-cache"> 
  7 <meta http-equiv="expires" content="0"> 
  8 <meta http-equiv="keywords" content="Canvas,File,Image"> 
 10 <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> 
 11 <script> 
 12 // 参数,最大高度 
 13 var MAX_HEIGHT = 100; 
 14 // 渲染 
 15 function render(src){ 
 16     // 创建一个 Image 对象 
 17     var image = new Image(); 
 18     // 绑定 load 事件处理器,加载完成后执行 
 19     image.onload = function(){ 
 20     // 获取 canvas DOM 对象 
 21     var canvas = document.getElementById("myCanvas"); 
 22     // 如果高度超标 
 23     if(image.height > MAX_HEIGHT) { 
 24     // 宽度等比例缩放 *= 
 25     image.width *= MAX_HEIGHT / image.height; 
 26     image.height = MAX_HEIGHT; 
 27     } 
 28     // 获取 canvas的 2d 环境对象, 
 29     // 可以理解Context是管理员,canvas是房子 
 30     var ctx = canvas.getContext("2d"); 
 31     // canvas清屏 
 32     ctx.clearRect(0, 0, canvas.width, canvas.height); 
 33     // 重置canvas宽高 
 34     canvas.width = image.width; 
 35     canvas.height = image.height; 
 36     // 将图像绘制到canvas上 
 37     ctx.drawImage(image, 0, 0, image.width, image.height); 
 38     // !!! 注意,image 没有加入到 dom之中 
 39     }; 
 40     // 设置src属性,浏览器会自动加载。 
 41     // 记住必须先绑定事件,才能设置src属性,否则会出同步问题。 
 42     image.src = src; 
 43 }; 
 44 // 加载 图像文件(url路径) 
 45 function loadImage(src){ 
 46     // 过滤掉 非 image 类型的文件 
 47     if(!src.type.match(/image.*/)){ 
 48     if(window.console){ 
 49     console.log("选择的文件类型不是图片: ", src.type); 
 50     } else { 
 51     window.confirm("只能选择图片文件"); 
 52     } 
 53     return; 
 54     } 
 55     // 创建 FileReader 对象 并调用 render 函数来完成渲染. 
 56     var reader = new FileReader(); 
 57     // 绑定load事件自动回调函数 
 58     reader.onload = function(e){ 
 59     // 调用前面的 render 函数 
 60     render(e.target.result); 
 61     }; 
 62     // 读取文件内容 
 63     reader.readAsDataURL(src); 
 64 }; 
 65 // 上传图片,jQuery版 
 66 function sendImage(){ 
 67     // 获取 canvas DOM 对象 
 68     var canvas = document.getElementById("myCanvas"); 
 69     // 获取Base64编码后的图像数据,格式是字符串 
 70     // "data:image/png;base64,"开头,需要在客户端或者服务器端将其去掉,后面的部分可以直接写入文件。 
 71     var dataurl = canvas.toDataURL("image/png"); 
 72     // 为安全 对URI进行编码 
 73     // data%3Aimage%2Fpng%3Bbase64%2C 开头 
 74     var imagedata = encodeURIComponent(dataurl); 
 75     //var url = $("#form").attr("action"); 
 76     // 1. 如果form表单不好处理,可以使用某个hidden隐藏域来设置请求地址 
 77     // <input type="hidden" name="action" value="receive.jsp" /> 
 78     var url = $("input[name='action']").val(); 
 79     // 2. 也可以直接用某个dom对象的属性来获取 
 80     // <input > 
 81     // var url = $("#imageaction").attr("action"); 
 82     // 因为是string,所以服务器需要对数据进行转码,写文件操作等。 
 83     // 个人约定,所有http参数名字全部小写 
 84     console.log(dataurl); 
 85     //console.log(imagedata); 
 86     var data = { 
 87     imagename: "myImage.png", 
 88     imagedata: imagedata 
 89     }; 
 90     jQuery.ajax( { 
 91     url : url, 
 92     data : data, 
 93     type : "POST", 
 94     // 期待的返回值类型 
 95     dataType: "json", 
 96     complete : function(xhr,result) { 
 97     //console.log(xhr.responseText); 
 98     var $tip2 = $("#tip2"); 
 99     if(!xhr){ 
100     $tip2.text('网络连接失败!'); 
101     return false; 
102     } 
103     var text = xhr.responseText; 
104     if(!text){ 
105     $tip2.text('网络错误!'); 
106     return false; 
107     } 
108     var json = eval("("+text+")"); 
109     if(!json){ 
110     $tip2.text('解析错误!'); 
111     return false; 
112     } else { 
113     $tip2.text(json.message); 
114     } 
115     //console.dir(json); 
116     //console.log(xhr.responseText); 
117     } 
118     }); 
119 }; 
120 function init(){ 
121     // 获取DOM元素对象 
122     var target = document.getElementById("drop-target"); 
123     // 阻止 dragover(拖到DOM元素上方) 事件传递 
124     target.addEventListener("dragover", function(e){e.preventDefault();}, true); 
125     // 拖动并放开鼠标的事件 
126     target.addEventListener("drop", function(e){ 
127     // 阻止默认事件,以及事件传播 
128     e.preventDefault(); 
129     // 调用前面的加载图像 函数,参数为dataTransfer对象的第一个文件 
130     loadImage(e.dataTransfer.files[0]); 
131     }, true); 
132     var setheight = document.getElementById("setheight"); 
133     var maxheight = document.getElementById("maxheight"); 
134     setheight.addEventListener("click", function(e){ 
135     // 
136     var value = maxheight.value; 
137     if(/^d+$/.test(value)){ 
138     MAX_HEIGHT = parseInt(value); 
139     } 
140     e.preventDefault(); 
141     },true); 
142     var btnsend = document.getElementById("btnsend"); 
143     btnsend.addEventListener("click", function(e){ 
144     // 
145     sendImage(); 
146     },true); 
147 }; 
148 window.addEventListener("DOMContentLoaded", function() { 
149 // 
150 init(); 
151 },false); 
152 </script> 
153 </head> 
154 <body> 
155 <div> 
156 <h1>通过Canvas及File API缩放并上传图片</h1> 
157 <p>从文件夹拖动一张照片到下方的盒子里, canvas 和 JavaScript将会自动的进行缩放.</p> 
158 <div> 
159 <input type="text" /> 
160 <button >设置图片最大高度</button> 
161 <input type="hidden" name="action" value="receive.jsp" /> 
162 </div> 
163 <div > 
164 <div >拖动图片文件到这里...</div> 
165 <div> 
166 <div> 
167 <button ></span> 
168 </div> 
169 </div> 
170 <div><h4>缩略图:</h4></div> 
171 <div > 
172 <canvas ></canvas> 
173 </div> 
174 </div> 
175 </div> 
176 </body> 
177 </html>