天天看点

移动端图片上传的两种方式

前段时间一直在做公司的项目,开发中遇到了图片上传的功能,由于是第一次调用微信接口实现多图上传,处处是坑啊,现总结一下开发中的问题,分享出来,以便后续有类似功能时直接查看使用,不必两眼一抹黑的开发了。

一 基于微信提供的API开发多图上传

(1) 微信js-sdk有两种,我们在开发中需要搞清楚自己到底是调用哪个平台的接口,两种sdk大同小异

一种是我们平时使用的js-sdk(微信JS-SDK说明文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115)

另一种就是企业号开发的sdk

(企业号开发者中心:http://qydev.weixin.qq.com/wiki/index.php?title=%E5%BE%AE%E4%BF%A1JS-SDK%E6%8E%A5%E5%8F%A3#.E5.9B.BE.E5.83.8F.E6.8E.A5.E5.8F.A3)

(2)配置相关

在我们使用sdk前,需要在后台配置我们项目打包上线后需要用的可信域名(即:JS接口安全域名),配置该域名时会随机生成一个txt文件,我们需要将该文件放置在网站的根目录下并且确保能访问,否则的话我们是调用不了各接口的,接下来就是根据官方文档提供的步骤配置config。

config接口注入权限验证配置中的签名串(signature)需要注意的是url参数,在安卓手机上该参数是当前页面的URL地址,但是在ios上,是用进入页的url去参与签名,所以会一直报签名失败,对于单页应用的Vue来说,我们需要再调用各接口的时候先刷新下页面获取到正确的URL后再去做签名算法,这是我们在开发中需要多加注意的。

(3)图片上传操作

1 调用拍照或从手机相册中选图接口

wx.chooseImage({

count: 1, // 默认9

sizeType: [‘original’, ‘compressed’], // 可以指定是原图还是压缩图,默认二者都有

sourceType: [‘album’, ‘camera’], // 可以指定来源是相册还是相机,默认二者都有

success: function (res) {

var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片

}

});

2 上传图片接口

wx.uploadImage({

localId: ”, // 需要上传的图片的本地ID,由chooseImage接口获得

isShowProgressTips: 1, // 默认为1,显示进度提示

success: function (res) {

var serverId = res.serverId; // 返回图片的服务器端ID,这是微信服务器的图片ID

// 调用自己的接口实现上传数据

}

});

备注:上传图片有效期3天,可用微信多媒体接口下载图片到自己的服务器,此处获得的 serverId 即 media_id。

虽然我们选择了多张图片,但是在上传的时候微信不支持把所选图片一次性上传,所以最终还是得一张一张上传,因此需要一个递归函数去多次执行

3 将上传的图片从微信服务器下载到自己的服务器上,这里需要使用素材管理中的获取临时素材接口

http请求方式: GET,https调用

https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID

企业号开发该接口地址:

https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID

这里的操作需要在后端实现,该接口返回的是一个供下载的图像流,我们可以请求该地址,将返回内容直接写入本地服务器就是一个图片,然后可以返回一个供前端使用的图片地址,前端就可以展示了。但是这样又增加了一次请求,体验性不是很好。

改进方法:既然图片是从本地获取到的,我们可以考虑直接使用上述1中返回的localIds展示本地图片,对于增加、删除操作,我们只需要将服务器返回地址与localIds相关联就可以解决,这样的话减少了http请求并且能够快速显示出所选图片来,何乐而不为呢。

到这以为图像的上传跟展示已经完事了,但是。。。,可怕的但是出现了

在ios下,localIds无法作为img的src显示,需要调用专门为iOS准备的获取本地图片接口(wx.getLocalImgData)

wx.getLocalImgData({

localId: ”, // 图片的localID

success: function (res) {

var localData = res.localData; // localData是图片的base64数据,可以用img标签显示

}

});

此处的localId是一个图片的id,不可把localIds一次传入,所以还是需要自己写个递归函数多次调用

到此,基于微信的多图上传告一段落

二 使用megapix-image 实现移动端图片上传

该插件原理是使用Canvas压缩图片上传,使用该插件的大体思路是

1 页面初始化一个input标签跟一个img标签,input标签用来获取选择的图片资源,其内容存放在document.getElementById(‘inputid‘).files[0]中,img标签用来展示选择的图片的base64码

2 构造一个MegaPixImage函数

eg: mpImg = new MegaPixImage(file);,file即为document.getElementById(‘inputid‘).files[0]

MegaPixImage有一个render方法,该方法接受几个参数,第一个参数:img标签,第二个参数是一个对象:可以设置图像的大小跟压缩比{maxHeight: 500,maxWidth: 500, quality: 0.6}, 第三个参数是回调函数,回调函数默认参数是图片的base64码

例:

var fileInput = document.getElementById(‘cameraInput‘);

var file = fileInput.files[0];

var mpImg = new MegaPixImage(file);

var resCanvas1 = document.getElementById(‘myCanvas‘);
        var _max = 320;
        mpImg.render(resCanvas1, {
            maxHeight: _max
        },callback);
           

callback中便可以写自己的业务逻辑代码。

3 服务端处理

服务端获取到base64 码,将以 “data:image/png;base64,”开头的字符串截取后的剩余字符串写入文件,即是一张可打开的图片,然后返回前端成功标志,前端便可以按照约定好的路径格式读取文件了

继续阅读