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 id="imageaction" type="hidden" action="receive.jsp"> 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" id="maxheight" value="100"/> 160 <button id="setheight">设置图片最大高度</button> 161 <input type="hidden" name="action" value="receive.jsp" /> 162 </div> 163 <div id="preview-row"> 164 <div id="drop-target" style="width:400px;height:200px;min-height:100px;min-width:200px;background:#eee;cursor:pointer;">拖动图片文件到这里...</div> 165 <div> 166 <div> 167 <button id="btnsend"> 上 传 </button> <span id="tip2" style="padding:8px 0;color:#f00;"></span> 168 </div> 169 </div> 170 <div><h4>缩略图:</h4></div> 171 <div id="preview" style="background:#f4f4f4;width:400px;height:200px;min-height:100px;min-width:200px;"> 172 <canvas id="myCanvas"></canvas> 173 </div> 174 </div> 175 </div> 176 </body> 177 </html>