微信小程序拍照上传功能最佳实践
微信小程序拍照上传功能最佳实践
随着移动互联网的快速发展,微信小程序已成为开发者构建轻量级应用的重要平台。其中,拍照上传功能是许多小程序不可或缺的一部分,广泛应用于社交、电商、办公等多个场景。本文将详细介绍如何在微信小程序中实现高效稳定的拍照上传功能,从前后端代码实现到用户体验优化,全方位展示最佳实践方案。
基本功能实现
在微信小程序中实现拍照上传功能,主要涉及两个关键API:wx.chooseMedia
和wx.uploadFile
。
前端代码实现
wx.chooseMedia
用于拍摄照片或从手机相册中选择图片。以下是一个基本的使用示例:
function test() {
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['camera'],
camera: 'back',
success(res) {
console.log(res);
},
fail(res) {
console.log(res);
}
});
}
主要参数说明:
count
:最多可以选择的文件个数mediaType
:文件类型,可选值为['image']
、['video']
或['image', 'video']
sourceType
:文件来源,可选值为['album']
、['camera']
或['album', 'camera']
camera
:仅在sourceType
为camera
时生效,可选值为'back'
或'front'
回调参数res
包含:
tempFiles
:本地临时文件列表,其中的tempFilePath
是本地临时文件路径type
:文件类型
获取到临时文件路径后,可以使用wx.uploadFile
将其上传到服务器:
// 拍摄照片
photoCapture() {
let that = this;
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['camera'],
camera: 'back',
success(res) {
that.setData({
photoLink: res.tempFiles[0].tempFilePath,
});
console.log(res.tempFiles[0].tempFilePath);
console.log('图片拍摄成功');
wx.showLoading({
title: '正在上传图片',
mask: true,
});
// 图片上传
wx.uploadFile({
url: 'http://localhost:5000/uploadImage',
filePath: res.tempFiles[0].tempFilePath,
name: 'photo',
formData: {
fileName: 'photoTest.png',
},
success(res) {
wx.showToast({
title: '图片上传成功',
});
},
});
},
fail(res) {
console.log('图片拍摄失败');
},
});
}
后端代码实现
后端可以使用Flask框架来接收和存储上传的文件:
from flask import Flask, request
import os
app = Flask(__name__)
@app.route('/uploadImage', methods=["POST"])
def uploadImage():
video = request.files['photo'].stream.read()
name = request.form['fileName']
if not files_exists(name, 2):
file_path = os.getcwd() + '\\images\\' + name
with open(file_path, 'ab') as f:
f.write(video)
return 'image upload success'
else:
return 'image already exist'
def files_exists(file_name, choice):
if choice == 1:
path = os.getcwd() + '\\videos\\'
video_path = os.path.join(path, file_name)
return os.path.isfile(video_path)
else:
path = os.getcwd() + '\\images\\'
image_path = os.path.join(path, file_name)
return os.path.isfile(image_path)
if __name__ == '__main__':
app.run(host='127.0.0.1', port=5000)
常见问题与解决方案
审核问题
在实际开发中,拍照上传功能可能会遇到微信小程序的审核问题。例如,有开发者反映即使明确表示不是人脸识别功能,仍然被要求使用人脸识别的原生接口。这可能与微信对隐私和安全的严格要求有关。建议在提交审核时详细描述功能用途,确保符合微信的相关政策。
上传速度慢
对于图片上传速度慢的问题,可以通过压缩图片来优化。例如,使用wx.compressImage
API对图片进行压缩:
touchphoto() {
const that = this;
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera'],
maxDuration: 30,
camera: 'back',
success(res) {
var tempFile = res.tempFiles;
console.log(tempFile);
wx.compressImage({
src: tempFile[0].tempFilePath, // 图片路径
quality: 80, // 压缩质量
success(result) {
console.log(result.tempFilePath);
wx.showLoading({
title: '系统处理中',
});
that.upLoadIdImg(result.tempFilePath);
},
fail() {
that.upLoadIdImg(tempFile[0].tempFilePath);
}
});
}
});
}
用户体验优化
为了提升用户体验,可以考虑以下优化方案:
自动抓拍功能
在某些场景下,自动抓拍功能可以提供更便捷的用户体验。例如,使用<camera>
组件实现定时抓拍:
<template>
<view class="container">
<view class="check-img">
<!-- 视频组件 -->
<camera device-position="back" class="img" flash="off" @error="error" style="width: 100vw; height: 60vh;">
</camera>
<!-- 对准框 -->
<div class="camera2" :style="{ 'background-image': `url(${kuankuan})` }"></div>
<!-- 扫描动画 -->
<view class="check-await"></view>
</view>
</view>
</template>
<script>
import {
codeDecodeAPI
} from '@/api/myApi.js'
export default {
data() {
return {
kuankuan: this.$store.state.baseUrl + '/images_fjfw/kuankuan.png',
timer: null
}
},
onLoad(option) {},
onShow() {
this.changeAvatar()
},
mounted() {},
components: {},
filters: {},
watch: {},
computed: {},
methods: {
//关闭抓拍
stopCamera() {
clearInterval(this.timer);
this.timer = null;
},
//调用摄像头
changeAvatar() {
const cameraContext = uni.createCameraContext();
this.timer = setInterval(() => {
cameraContext.takePhoto({
quality: 'high',
success: res => {
const src = res.tempImagePath
console.log(src, 'res.tempImagePath');
const base64_dt = uni.getFileSystemManager().readFileSync(src, 'base64')
const fileName_dt = src.lastIndexOf('.') // 取到文件名开始到最后一个点的长度
const base64_img = 'data:image/' + fileName_dt + ';base64,' + base64_dt
codeDecodeAPI({
qr_image: base64_img
}).then(res => {
if(res.code=='2'){
uni.navigateTo({
url: '/pages/nonono/nonono'
})
this.stopCamera()
}else if (res.data.consistent == '1') {
console.log('同一个人')
uni.navigateTo({
url: '/pages/okBuy/okBuy?item=' + JSON.stringify(res.data)
})
this.stopCamera()
} else if (res.data.consistent == '2') {
console.log('不是同一个人')
uni.navigateTo({
url: '/pages/warn/warn?item=' + JSON.stringify(res.data)
})
this.stopCamera()
}
}).catch(err => {
console.log(err);
})
},
fail: err => {
console.error('拍照失败', err);
}
});
}, 3000);
}
},
}
</script>
压缩图片
如上文所述,使用wx.compressImage
对图片进行压缩可以显著提升上传速度,同时保持图片质量。
安全性与性能优化
在实现拍照上传功能时,还需要考虑安全性问题。例如,需要对上传的文件类型和大小进行限制,防止恶意文件上传。可以在后端代码中添加相应的检查逻辑:
@app.route('/uploadImage', methods=["POST"])
def uploadImage():
if 'photo' not in request.files:
return 'No file part'
file = request.files['photo']
if file.filename == '':
return 'No selected file'
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return 'File uploaded successfully'
else:
return 'Invalid file type'
其中,allowed_file
函数用于检查文件类型:
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
此外,还可以通过限制请求频率、使用HTTPS传输等方式进一步提升安全性。
最佳实践总结
代码规范:确保前后端代码遵循良好的编程规范,使用清晰的变量命名和注释,便于维护和理解。
性能优化:使用图片压缩技术优化上传速度,同时考虑服务器的存储和处理能力,合理设置图片大小和分辨率。
用户体验:提供友好的用户界面和交互,如进度提示、错误处理和自动抓拍功能,提升用户满意度。
安全性:严格检查上传的文件类型和大小,使用HTTPS传输保护数据安全,防止恶意文件上传。
通过以上最佳实践,开发者可以实现一个既高效又安全的拍照上传功能,为用户提供优质的使用体验。