angularjs之手机端input图片上传(续)
来源:互联网 发布:满文翻译软件 编辑:程序博客网 时间:2024/09/21 09:26
为啥要写个续呢?解决一个问题:图片压缩
BTW,本文是针对ajax提交,如果本身就是form表单提交就不需要看了。
上一篇里说到h5可以用FileReader获取到图片信息,如base64,按道理这就可以传给服务端了,但是当图片很大的时候,这个字符串可能会写满好几张a4纸,这显然不合适,再者字符串太大服务端也接受不到- -于是发送之前压缩一下是个不错的选择,上代码:
var zipPic=function (result) { var canvas=document.getElementById("uploadImg"); var cxt=canvas.getContext('2d'); var img=new Image(); img.src= result; canvas.width=640; canvas.height=640*(img.height/img.width); cxt.drawImage(img,0,0,640,canvas.height); return canvas.toDataURL("image/jpeg",0.9); }
cxt.drawImage会将result所代表的图片绘制到canvas上去,并且重新指定了图片的宽高,
drawImage有3个方法:
在画布上定位图像:
context.drawImage(img,x,y);
在画布上定位图像,并规定图像的宽度和高度:
context.drawImage(img,x,y,width,height);
剪切图像,并在画布上定位被剪切的部分:
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
具体参数意思可以到w3school去看。
canvas.toDataURL就是压缩过后的base64,第一个参数是格式,有的时候传的图片时png什么的都可以转成jpg,第二个参数可以理解为画面质量,0~1,很好理解。
ok,到此为止,一切都很美好,然而……
以上方法在Android上都运行正常,然后在ios上toDataURL取到的却是空,百度之,发现ios自带canvas坑(以下摘自http://www.cnblogs.com/zhwl/p/4961473.html):
首先是图片的大小,如果图片的大小超过两百万像素,图片也是无法绘制到canvas上的,调用drawImage的时候不会报错,但是你用toDataURL获取图片数据的时候获取到的是空的图片数据。
再者就是canvas的大小有限制,如果canvas的大小大于大概五百万像素(即宽高乘积)的时候,不仅图片画不出来,其他什么东西也都是画不出来的。
应对第一种限制,处理办法就是瓦片绘制了。瓦片绘制,也就是将图片分割成多块绘制到canvas上,我代码里的做法是把图片分割成100万像素一块的大小,再绘制到canvas上。
应对第二种限制,我的处理办法是对图片的宽高进行适当压缩,我代码里为了保险起见,设的上限是四百万像素,如果图片大于四百万像素就压缩到小于四百万像素。四百万像素的图片应该够了,算起来宽高都有2000X2000了。
定义两个canvas:
var canvas = document.createElement("canvas"); var ctx=canvas.getContext('2d'); var tCanvas = document.createElement("canvas"); var tctx = tCanvas.getContext("2d");代码片
压缩方法:
//使用canvas对大图片进行压缩 function compress(img) { var width = img.width; var height = img.height; //如果图片大于四百万像素,计算压缩比并将大小压至400万以下 var ratio; if ((ratio = width * height / 4000000) > 1) { ratio = Math.sqrt(ratio); width /= ratio; height /= ratio; } else { ratio = 1; } canvas.width = width; canvas.height = height; // 铺底色 ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); //如果图片像素大于100万则使用瓦片绘制 var count; if ((count = width * height / 1000000) > 1) { count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片 // 计算每块瓦片的宽和高 var nw = ~~(width / count); var nh = ~~(height / count); tCanvas.width = nw; tCanvas.height = nh; for (var i = 0; i < count; i++) { for (var j = 0; j < count; j++) { tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh); ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh); } } } else { ctx.drawImage(img, 0, 0, width, height); } //进行最小压缩 var ndata = canvas.toDataURL('image/jpeg', 0.1); // console.log('压缩前:' + initSize); // console.log('压缩后:' + ndata.length); // console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%"); tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0; return ndata; }
压缩方法有了,还要注意一点就是调用的时候,我当时在这花了蛮久时间0.0
reader.onload = function (e) { var result=this.result; $scope.success.up = true; var img=new Image(); img.src= result; var maxsize = 100 * 1024; if(result.length<=maxsize){ transferImgSrc=result; }else { if(img.complete){//一定要等图片加载完了再调压缩 callback(); }else { img.onload=callback; } function callback() { transferImgSrc = compress(img);//此处得到base64 img = null; } } }
- angularjs之手机端input图片上传(续)
- angularjs之手机端input图片上传
- angularjs手机webapp 利用input拍照,图库选择上传图片
- AngularJS 上传图片 手机端 安卓内置浏览器 无法上传
- 手机端上传图片
- 手机端图片上传
- html5手机 input file 上传图片 调用API
- html5手机 input file 上传图片 调用API
- 使用php://input接收手机图片上传二进制流
- 使用php://input接收手机图片上传二进制流
- AngularJS之input指令
- angularjs上传图片预览
- angularjs图片上传
- angularjs 图片上传 回显
- angularJS上传图片预览
- WebUploader 手机端上传图片
- bootstrap-input 上传图片
- input file上传图片
- 一个高大上的Log工具
- linux配置多台服务器系统时间一致
- java中的IO最全整理
- 揭开AssetBundle庐山真面目(一)
- 浏览器的工作原理
- angularjs之手机端input图片上传(续)
- 基本数据类型的常量的情况下
- Javase 专题 反射和动态代理 aop
- Eclipse安装Maven插件
- 倾斜的Texview
- SpringMVC 基于注解的Controller @RequestMapping @RequestParam..
- C#Winform连接摄像头
- IOS-OC 高德地图自定义锚点+点击事件处理
- android开发之日常