最近在做小程序电商购物评价晒图,用到了小程序上传图片功能,谈谈一路过来踩的坑以及解决方案;
问题一:
一般手机自带相机拍的照片过大(基本上都是3-6MB之间),图片大上传慢体验差
根据往常H5开发经验首先想到的就是利用 canvas 按照宽高比例重新绘制选择的图片,然后导出图片在传给后台服务器保存;用到小程序以下接口:
wx.chooseImage(Object object)从本地相册选择图片或使用相机拍照
wx.getImageInfo(Object object)获取图片信息。网络图片需先配置download域名才能生效。
wx.createCanvasContext(string canvasId, Object this)创建 canvas 的绘图上下文 CanvasContext 对象
CanvasContext.drawImage(string imageResource, number sx, number sy, number sWidth, number sHeight, number dx, number dy, number dWidth, number dHeight) 绘制图像到画布
CanvasContext.draw(boolean reserve, function callback) 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。
wx.canvasToTempFilePath(Object object, Object this) 把当前画布指定区域的内容导出生成指定大小的图片。在 draw()
回调里调用该方法才能保证图片导出成功。
wx.uploadFile(Object object)
将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求,其中 content-type
为 multipart/form-data
。使用前请注意阅读相关说明。
上代码说坑与解决方法
1.第一个坑理解不足,创建不了ctx CanvasContext 对象
原来我wxml文件中没有添加 canvas 组建对象(跟H5有些区别) ,添加一个canvas 主键即可
2.第二个坑 ctx.draw方法不执行
原来是wxml中组件带了隐藏属性导致(本来计划隐藏临时展示图片等上传完成了使用数组绘制图片的看来不行),修改如下
3.第三个坑 要指定 组件宽高为目标宽高,不然还是绘制不出来
修改如下
效果:
接下来就是加代码,导出图片传给后台,并绘制上传图片,第一版代码如下
这里在编辑器中使用模拟器调式的时候,会遇到第四个坑 uploadFile上传成功返回值并不是json对象,需要截取转换对象在判断
此时模拟器中已经ok并且可以正常走通逻辑
接下来是进行真机调式,遇到 第五坑 CanvasContext.draw 回调不执行
查询文档发现模拟器由于是在电脑上面性能比较好绘制的比较快,所以可以在draw绘制之后的回调中使用canvasToTempFilePath方法立即拿到导出文件,但是在真机调式中由于手机性能低下(Android居多)draw方法之后需要给出一定的延迟时间等绘制成功后才能导出图片,所以修改成一下代码
注意标记 that 是当前容器变量请使用 如 下外层方法定义
做了如上修改之后 有些性能相对比较好的手机是可以通过canvasToTempFilePath拿到图片的,但是中国Android手机相当多,还有性能更低下的(没有测试的程序员就吃这个亏);你的手机可以了不代表体验者客户的手机就可以(因为有可能客户的手机比你的手机性能还差,汗);说白了200毫秒延迟有的手机能完成绘制,有的手机还是不能够完成绘制(性能更低下)需要更长的延迟时间,解决关键在于针对不同性能手机给出不同长度的延迟时间,才可以;世上手机千千万总不能都拿来测试一遍每个手机需要多久的延迟时间,苦逼程序员啊;
天无绝人之路,draw方法只能执行一次,但是canvasToTempFilePath可以执行多次,利用它的fail机制加回调,一次没拿到我多来几次总有你把图画好的时候我就拿到了;代码是咧 封装一个方法,进行回调 上代码封装一个外部方法如下
draw回调方法里面调动这个外部方法
如此即可解决真机调式如遇性能差的手机不能通过canvasToTempFilePath拿到图片也既CanvasContext.draw 回调不执行问题解决,其实是执行了draw的只是没绘制好canvasToTempFilePath拿不到导出图片
下面说说 第六坑 体验小程序不能上传图片到后台 报uploadFile url not in domain list
这个主要是 开发工具真机调式的时候 不检测 https域名,所以调式的时候体现不出来,体验版就体现出来了
去小程序后台配置 uploadFile安全域名,注意生效时间 说是立即其实 有可能很久 我当时配置后生效时间是三个小时候在测试体验版就ok了
上传附件有么有方法?