引言
最近公司需要做个冲印类型的小程序,一阵徘徊后,才决定快速集成一个微型产品来。
正题
几乎每个程序都需要用到图片。
在小程序中我们可以通过image组件显示图片。
当然小程序也是可以上传图片的,参照微信小程序官方文档。
step_1 选择图片
- 通过
wx.chooseImage(OBJECT)
实现

官方示例代码:
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths }
})
图片最多只可以选择9张, 也可以通过拍摄照片实现,当选择完图片之后会获取到图片路径, 这个路径在本次启动期间有效。
如果需要保存就需要用wx.saveFile(OBJECT)
step_2 上传图片
- 通过
wx.uploadFile(OBJECT)
可以将本地资源文件上传到服务器。
原理就是客户端发起一个 HTTPS POST
请求,其中 content-type
为 multipart/form-data
。
官方示例代码
wx.chooseImage({
success: function(res) {
var tempFilePaths = res.tempFilePaths
wx.uploadFile({
url: 'http://example.weixin.qq.com/upload', //仅为示例,非真实的接口地址
filePath: tempFilePaths[0],
name: 'file',
formData:{
'user': 'test'
},
success: function(res){
var data = res.data
//do something
}
})
}
})
示例代码
看完了文档, 写一个上传图片就没有那么麻烦了,下面是真实场景的代码
import constant from '../../common/constant';
Page({
data: {
src: "../../image/photo.png", //绑定image组件的src
//略...
},
onLoad: function (options) {
//略...
},
uploadPhoto() {
var that = this;
wx.chooseImage({
count: 1, // 默认9
sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths;
upload(that, tempFilePaths);
}
})
}
})
function upload(page, path) {
wx.showToast({
icon: "loading",
title: "正在上传"
}),
wx.uploadFile({
url: constant.SERVER_URL + "/FileUploadServlet",
filePath: path[0],
name: 'file',
header: { "Content-Type": "multipart/form-data" },
formData: {
//和服务器约定的token, 一般也可以放在header中
'session_token': wx.getStorageSync('session_token')
},
success: function (res) {
console.log(res);
if (res.statusCode != 200) {
wx.showModal({
title: '提示',
content: '上传失败',
showCancel: false
})
return;
}
var data = res.data
page.setData({ //上传成功修改显示头像
src: path[0]
})
},
fail: function (e) {
console.log(e);
wx.showModal({
title: '提示',
content: '上传失败',
showCancel: false
})
},
complete: function () {
wx.hideToast(); //隐藏Toast
}
})
}
后端代码
后端是用java写的,一开始的时候,后端开始用了一些框架接收上传的图片,出现了各种问题,后来使用了纯粹的Servlet就没有了问题, 把代码贴出来省的以后麻烦了。
注意: 代码使用了公司内部的框架,建议修改后再使用
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Logger logger = LoggerFactory.getLogger(FileUploadServlet.class);
public FileUploadServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
JsonMessage
小程序前端效果____仿朋友圈的照片上传。
很粗糙、很简陋,请勿怪。
先上图:
首先说明一下我的前端基本诉求:
- 一行明确指定图片显示个数
- 可从照片图库一次多选若干张照片并显示在前端
- 照片与照片之间有明显的间隔
- 达到一定数量照片时将添加按钮隐藏
- 添加按钮加上一些样式
index.wxml
index.wxss
.uploadContainer {
display: flex;
flex-direction: row;
justify-content: flex-start;
flex-wrap: wrap;
}
.addimg {
border-style: inset;
border-width: 1px;
border-color: #ddd;
}
index.js
//index.js
//获取应用实例
var app = getApp()
var px2rpx = 2, windowWidth = 375;
Page({
/**
* 页面的初始数据
*/
data: {
pic_width: 300, //初始化值
pic_height: 300, //初始化值
img_button: 'inline-block',
image: [],
msg: '',
margin_length: 3,//显示图片的外边距margin值(单位:px像素)
},
//事件处理函数
onLoad: function () {
console.log('onLoad');
wx.getSystemInfo({
success: function (res) {
windowWidth = res.windowWidth;
px2rpx = 750 / windowWidth;
}
})
this.setData({
pic_width: (windowWidth - 8 * this.data.margin_length) / 4,
pic_height: (windowWidth - 8 * this.data.margin_length) / 4
})
},
onPullDownRefresh: function () {
wx.stopPullDownRefresh()
},
onShareAppMessage: function () {
return {
title: 'xx公司',
path: 'pages/index/index'
}
},
uploadImg: function () {
var that = this;
var image = this.data.image;
//设定最终一起上传照片的最大数量
if (this.data.image.length < 101) {
wx.chooseImage({
count: 9, // 默认9
sizeType: ['original'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
wx.uploadFile({
url: app.appUrl.url + 'upload',//这个方法就是后台处理上传的方法
filePath: res.tempFilePaths[0], //获取到上传的图片
name: 'file',
success: function (info) {
console.log(info);//info.data就是上传成功的图片名称 您可以在wxml里面搞一个隐藏域存储起来,在上面Submit提交里拼装一块提交出去
}
})
},
complete: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
console.log(res.tempFilePaths);
//判空处理,不能使用res.tempFilePaths.length方法,会报空指针
//解决了取消选择照片时会将空照片上传的问题
if(res.tempFilePaths!=null){
//语法:concat的用法,concat之后返回的是一个新的对象,因此要赋值给image
image=image.concat(res.tempFilePaths);
that.setData({ image: image })
//当有100张照片上传时,将上传图片的按钮隐藏掉
if (that.data.image.length == 100) {
that.setData({
img_button: 'none',
})
}
}
}
})
}
},
deleteImg: function (e) {
var image = this.data.image;
image.splice(e.currentTarget.dataset.num, 1);
this.setData({
image: image,
img_button: 'inline-block',
})
},
})