[置顶] html5调用相册修改头像
2016-01-08 14:50
801 查看
刚写完一个项目其中就有一个功能修改头像,这个写的我很是头疼。首先做这个有个很大的问题就是图片的压缩,因为用户可能会从手机中上传头像,而手机拍摄的图片往往会很大,所以不可能不对图片进行压缩。不压缩的话一个是上传慢,另一个就是用户产生的流量会很大。所以我们只能进行前端压缩。那么问题来了前端怎么压缩,我在网上找了大量的资料很多人都用jcrop这个控件来做,jcrop会将你上传的图剪裁然后显示出来,但是这个处理过程是在后台进行,说白了就是你还是把原图传到服务器,然后通过剪裁的参数生成剪裁后的图片,这样依然会产生很大的流量。这里我们采用canvas来进行客户端压缩,个人测试很好使想压缩多大就多大,任性!
首先我们在html中写一个显示头像的div。这里需要强调一点 为什么把img和input放到label下,因为我们需要隐藏这个input 但是隐藏后我们很难找到它的位置,于是我们将图片跟它放在一起,起到点击图片就能弹出相册的效果。
请求后台ajax,这里需要注意的是压缩后的突变是base64码,有个前缀我们需要把它截取掉。这样传到服务端才能正常解码。
服务端代码
至此来张效果图
首先我们在html中写一个显示头像的div。这里需要强调一点 为什么把img和input放到label下,因为我们需要隐藏这个input 但是隐藏后我们很难找到它的位置,于是我们将图片跟它放在一起,起到点击图片就能弹出相册的效果。
<div id="avatar" class="boxlist2 t1"> <label class="btn-file" data-role="add"> <img id = "#avatarImg" src="${user.avatar }" width="220" height="220" alt=""/> <input id="avatarFile" accept="image/*" name="avatarFile" type="file" style="display:none;" /> </label> </div>定义控件的点击事件以及图片地址变动后的监听事件
$(function() 4000 { var inputFile = document.getElementById('avatarFile') // 监听文件改变 inputFile.addEventListener('click', function() {this.value = null;}, false); inputFile.addEventListener('change', readData, false); })文件改变响应函数
// 文件改变响应 function readData(evt) { evt.stopPropagation(); evt.preventDefault(); var file = evt.dataTransfer !== undefined ? evt.dataTransfer.files[0] : evt.target.files[0]; if (!file.type.match(/image.*/)) {return;} var reader = new FileReader(); reader.onload = (function() { return function(e) { var img = new Image(); img.src = e.target.result; img.onload = (function() { var canvas = document.createElement('canvas'); canvas.width = 800; canvas.height = 800; var ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, canvas.width, canvas.height); // canvas清屏 //重置canvans宽高 canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 将图像绘制到canvas上 canvas.toDataURL("image/jpeg");//必须等压缩完才读取canvas值,否则canvas内容是黑帆布 cropAndUploadImage(canvas.toDataURL("image/jpeg")); }); } })(file); reader.readAsDataURL(file); }
请求后台ajax,这里需要注意的是压缩后的突变是base64码,有个前缀我们需要把它截取掉。这样传到服务端才能正常解码。
function cropAndUploadImage(base64){ var b64 = base64.split(",")[1]; var load = layerLoad(); $.ajax({ url: 'User!uploadImg.action', type: "post", data:{ photo : b64, }, dataType: 'json', success:function(data) { if(data.success){ setTimeout(function(){ window.location.reload(); },1000); }else { layer.close(load); layerOpen(date.error); } }, error : function() { // view("异常!"); layer.close(load); layerAlert("图片上传超时!"); } }) }
服务端代码
/** * 上传图片 * @return */ public String uploadImg() { JSONObject info = new JSONObject(); try { getRequest().setCharacterEncoding("utf-8"); getResponse().setCharacterEncoding("utf-8"); getResponse().setContentType("text/html"); int userid = (int)getSession().get("userid"); String path = "/image/user/"; // 对base64数据进行解码 生成 字节数组,不能直接用Base64.decode();进行解密 byte[] photoimg = new BASE64Decoder().decodeBuffer(photo); for (int i = 0; i < photoimg.length; ++i) { if (photoimg[i] < 0) { // 调整异常数据 photoimg[i] += 256; } } //byte[] photoimg = Base64.decode(photo);//此处不能用Base64.decode()方法解密,我调试时用此方法每次解密出的数据都比原数据大 所以用上面的函数进行解密,在网上直接拷贝的,花了好几个小时才找到这个错误(菜鸟不容易啊) File file = new File(getRequest().getServletContext().getRealPath(path), userid + ".JPEG"); if (!file.exists()) { file.createNewFile(); } FileOutputStream out = new FileOutputStream(file); out.write(photoimg); out.flush(); out.close(); /** * 更改数据库图片地址 */ // 图片地址存入数据库 这里就不详细介绍了
info.accumulate("success", true); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); info.accumulate("success", false).accumulate("error", "图片太大,设置失败"); } super.responsePrint(info.toString()); return null; }
至此来张效果图
相关文章推荐
- HTML5浏览器定位navigator.geolocation.getCurrentPosition
- Html5添加超级简洁实用的返回顶部插件教程
- html5 canvas 详细使用教程
- Html5添加切换缩略图模式和列表模式插件教程
- HTML5所有新标签总结
- Html5添加带备忘录功能的简单的日期选择器插件教程
- HTML5之服务器发送事件
- 基于HTML5的可预览多图片Ajax上传
- base64和图片的互转(HTML5的File实现)
- Html5添加用户选择一个日期时间范围的日期选择器插件教程
- HTML5之---Manifest 文件--离线缓存
- HTML5之客户端存储数据
- 程序猿学习新技术的10个建议
- (视频) 基于HTML5的服务器远程访问工具
- HTML5 应用程序缓存
- HTML5 Web Workers
- HTML5 服务器发送事件(Server-Sent Events)
- html5中必填项设置
- html5变化在哪里
- Html5添加支持触摸屏的响应式轮播图插件教程