美文网首页前端日报Web前端前端Vue专辑
html5 上传本地图片处理各种问题

html5 上传本地图片处理各种问题

作者: 乖小鬼 | 来源:发表于2015-12-16 12:06 被阅读11561次

这是最近给公司写一个项目,项目要求大概是这样子:
1.上传手机本地图片,然后裁剪(后加的需求)
2.能够旋转图片,用于裁剪(后面加的需求)
3.填写各种文字,选择颜色,之后把文字和2个相关的图片,水印到裁剪的图片上,上传服务器生成一个图片地址,返回,分享出去。

功能就是大概上面这些,其他的也就是各种小功能,不提了,技术选型说下,整体上使用 Vue(包括 router,resource,webpack等等)

那么这几个需求怎么做呢:
1、 本地上传,使用 html5 的 File Api 拿到图片的base64编码,赋值给img的src(坑1,2),然后弹出一个图层,进行裁剪,最开始裁剪是在img的上面套一个div来进行坐标计算,计算完了使用canvas来截取图片,然后取值(坑3)。
2、这个功能就是使用canvas的旋转图片解决,需要注意的是,旋转的时候要保持横纵比,而且要注意宽高的大小(坑4)。
3、使用canvas来叠加水印和图片即可,主要是注意坐标。

那么说说坑:
1、拿到src的base64编码,看似没有问题,实际上有个巨大的问题,很多图片在手机上显示为竖屏,但是拿到的base64编码,直接赋值给img的src后,发现是横屏的。最开始发现这种情况,以为是个别现象,最后不断尝试之后,发现是个非常普遍的情况,特别是IPhone手机,而且还分你选择的图片文件夹,相册和照片流同一张图片,一个横屏,一个竖屏。导致我完全不能理解这是为什么???基本一个下午耗在这个问题上了。

直到晚上回去,问我一个朋友IOS开发的大神,@叶孤城__,他告诉我,因为现在IPhone的摄像头就是横着的,手机里显示竖屏的原因是ios自己做了处理,他们可以根据图片的一个拍摄角度数值来判断横竖问题,但是这个数值在我们web端确拿不到,很是尴尬。那么怎么解决这个问题呢?? ------- 我使用的方案:旋转图片,可以让用户自己去主动旋转图片,选取角度。 还有另外一种解决方案,在坑2也用到,后面讲。

2、除了这个横屏之外,android手机有的上传,选择了图片之后,没有任何反应,我开始一度认为原因是不支持html5的File Api,所以没有显示出上传的图片,后面就各种debugger,发现原因是没有触发Input标签的change事件,而且不管怎么样都没有办法触发,为了解决这个问题,查阅了各种官方文档和stackoverflow之后,发现可以给 type="file"的input添加两个属性来表示手机上传图片。

 <input type="file" name="image" class="file-choose" id="file" accept="image/*" v-on:change="chooseFileChange($event)" capture/>

这样添加了 accept 和 capture之后,有问题的android手机,在选择图片的时候,有好几个文件夹,可以选择了,其中有的可以上传,有的不行,经常仔细的测试发现,sd卡上的图片是拿不到的,也就不会触发change事件,因为没有root权限去拿文件数据。又是一个无解问题,因为你的web在浏览器里面,权限就是低啊,(不得不吐槽下web的权限问题,妈蛋)怎么解决问题呢??? 绕过去,也就是说如果你的页面是嵌套在你们公司自己App里面的,就让App帮你,那么我们项目是微信传播的,一定在微信浏览器里面,所以可以调用微信的JSSDK的选择图片接口,他是可以越过这些权限,而且还有一个好处,就是解决坑1的问题,他会处理横屏问题,就是把看着竖屏,实际横屏的上传时都处理为竖屏,但是代价也不小,你要选择图片,拿到一个key,然后继续调用sdk传到微信的服务器,拿到一个serverid,这个id传给自己的服务端,让他们通过这个id,去微信下载图片到自己的服务器,返回给你一个Url。过程很曲折,而且下载次数有限制(可以跟微信申请加载限制);

参考: 微信 js sdk 选择图片接口

3、我们继续说坑,以上问题,解决了之后,就是裁剪了,开始我使用的方案是这样子的,获取到base64之后,赋值给一个img,然后在这个img上进行框选移动,计算坐标然后裁剪,pc端完全没有任何问题,效率很高,但是放到微信上面测试,发现3个问题(妈蛋,手机端就是坑,一个功能,3个不同的问题),第一个问题,大家都知道现在手机像素高,图片不小,上传过来之后,base64也不小,放到img的src中其实就是内存中了,导致整个微信特别容易崩溃(就是崩溃,他就崩溃了,微信就崩溃了---三遍),第二个问题,使用vue的on来绑定touch事件,响应很慢,移动一点都不平滑,而且也会崩溃,没错,又崩溃了。第三个问题,旋转要使用canvas转化,先去图片数据,转完后,在给图片src赋值,很麻烦。

解决方案: 统一使用canvas,不要再用img,知道裁剪完成了,把img的base64拿到就行,而且导出的时候,使用jpeg不要是png,降低一些画质,我觉得完全没有影响,也就是图片的裁剪,旋转都是canvas,事件建议直接原生绑定。

4、旋转的坑,这个的问题是我们必须保存住原始图片的数据,进行canvas先旋转然后drawImage,要不没有旋转出来,canvas自己的imageData,貌似没有办法旋转,我试了矩阵的方式好像都不行(也可能是自己数学不好!!!如果有人知道,就demo)。

以上就是这次项目,遇到的各种大坑,其他都是小的地方,不过总体来说,完成了任务,并且使用了新的技术Vue.js。Vue的component还是非常好用的,注意父子关系,props的继承就没问题了。

欢迎大家交流相关技术, 如果对Vue感兴趣,可以加QQ群: 364912432,240319632。

求打赏,求关注微博。O(∩_∩)O哈哈~

最后附上活动网址,微信客户端打开才能使用: 预测2046

欢迎各位参与玩耍。

相关文章

网友评论

  • 61b087db71c2: canvas画的图在pc端可以显示,但是在手机端不可以,这样怎么解决呀,
    乖小鬼:不可以是黑的,还是白的? 是图形出不来,还是崩溃了?原因有很多,最有可能是api不支持,或者你没有指定canvas的大小
  • 泺影:呵呵,2年前接了个这种活,以为1星期最多了,结果最后差点搞崩掉,简单的图片上传和带编辑真的是完全不同的东西,被坑的一塌糊涂,最后写出来的代码狗啃一样,iphone的旋转也没处理。上周产品跟我说要做个这种活动,我直接就拒绝了、 :sweat_smile:
    乖小鬼:@泺影 现在应该好多了,各种处理都能很完善了。可以考虑
  • a91d8ce8da0b:最近工作上需要用到,你用经验填的坑,希望我能走得平稳:kissing_heart:
  • LiYajie:不错,挺实用
  • 1936f41e40c3:坑还有很多,比如画布出来了,大图片要等好一会儿才出来,如何解决呀,那种性能不怎么的手机
    乖小鬼:@亽大笨蜑 你的canvas一定是在等图片加载完才做事情的。顺序不要搞错了。 性能不好的手机,就看是哪里不好了,是不支持canvas还是画的时候卡顿。如果不支持,就换方案,如果是卡顿,就减小图片的大小
  • JackWhite:图片横竖的状态是可以拿到的。参考下webuploader的源码 里面有。。
    乖小鬼:@JackWhite 找到了,而且找到了他们引用的原始文件,
    JackWhite:@乖小鬼 压缩图片生成缩略图那一段。
    乖小鬼:@JackWhite 能具体点么? 源码哪个文件,或者说哪个API,我当时找了很久
  • 8855152c8c95:有Demo吗 我现在也要实现 你描述的这个功能
    乖小鬼:@来开水 没有 demo。。。。 已经上线了东西。
  • dec17:有Demo可以参考吗?
    乖小鬼:@欧钟源 已经上线了,没有demo了,跟微信授权耦合比较紧了。

本文标题:html5 上传本地图片处理各种问题

本文链接:https://www.haomeiwen.com/subject/arwehttx.html