html5调用相册修改头像

刚写完一个项目其中就有一个功能修改头像,这个写的我很是头疼。首先做这个有个很大的问题就是图片的压缩,因为用户可能会从手机中上传头像,而手机拍摄的图片往往会很大,所以不可能不对图片进行压缩。不压缩的话一个是上传慢,另一个就是用户产生的流量会很大。所以我们只能进行前端压缩。那么问题来了前端怎么压缩,我在网上找了大量的资料很多人都用jcrop这个控件来做,jcrop会将你上传的图剪裁然后显示出来,但是这个处理过程是在后台进行,说白了就是你还是把原图传到服务器,然后通过剪裁的参数生成剪裁后的图片,这样依然会产生很大的流量。这里我们采用canvas来进行客户端压缩,个人测试很好使想压缩多大就多大,任性!

首先我们在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(){
		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;
	}

至此来张效果图


  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值