【教程】微信小程序如何拍摄图片及视频并上传到后台进行存储

需求分析

微信小程序 中需要使用手机拍摄照片以及视频上传到后台进行进一步的操作,需要解决以下两个问题:

  1. 微信小程序如何拍摄照片及视频
  2. 如何将拍摄的照片及视频上传到后台进行存储

解决方案

前端开发:微信小程序原生

后端开发:Flask

如何拍摄照片及视频

微信小程序如何拍摄照片及视频:使用wx.chooseMediaAPI来实现

该API用于拍摄或从手机相册中选择图片或视频,文档链接为:developers.weixin.qq.com/miniprogram...

简单示例:

javascript 复制代码
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'],默认值为['image','video'],意为即允许拍摄图片也允许拍摄视频
  • sourceType:文件来源,可选值为['album']/[ 'camera']/['album', 'camera'],默认值为['album', 'camera'],意为即允许从相册选择,也允许直接拍摄
  • camera:仅在 sourceType 为 camera 时生效,使用前置或后置摄像头,可选值为'back'/'front',默认值为'back'

回调参数res:

  • tempFiles:本地临时文件列表,其中的tempFilePath是本地临时文件路径,也是该示例中的核心参数;
  • type:文件类型

更多参数以及回调参数请参考官方文档

由上可知,我们首选需要调用wx.chooseMedia函数,选择拍摄照片或者视频,然后在回调函数中拿到本地临时文件路径,这样就获取到了拍摄的照片或视频,但我们拿到的并不是一个完整的.png/.mp4文件,而是一个临时文件链接,例如:http://tmp/z7bXVKwgyWTKcbc89c663afd501de1d27ed321f8591c.jpg

这样的文件链接可以在开发者工具中打开:

但该链接无法在外部进行访问,因此就涉及到如何将该链接所代表的文件上传到后台的问题;

这样的文件在小程序中被称为"本地临时文件",仅在当前生命周期内保证有效,重启之后不一定可用

更多内容请参考官方文档:developers.weixin.qq.com/miniprogram...

如何上传后台进行存储

如何将拍摄的照片及视频上传到后台进行存储:

  • 前端:使用wx.uploadFileAPI
  • 后端:使用request.files['photo'].stream.read()来读取文件

前端代码

有关wx.uploadFile可以参考:developers.weixin.qq.com/miniprogram...

主要参数有:

  • url:开发者服务器地址,即要访问的接口
  • filePath:要上传的文件路径(本地路径),这里即是通过wx.chooseMedia回调中的tempFilePath
  • formData:HTTP 请求中其他额外的 form data,允许我们传输文件的时候携带一些其他的参数,比如说文件名称;

因此完整的前端代码如下(上传图片):

javascript 复制代码
//拍摄照片
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进行开发

通过request.files来接收文件

通过request.form来接收wx.uploadFileformData中携带的数据

通过write方法将接收到的文件保存到本地

因此完整的后端代码如下(上传图片):

sql 复制代码
app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello World'

# 图片上传
@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)

运行结果

首先启动后端服务,然后小程序初始页面如下:

点击按钮拍摄图片,可以看到图片成功预览在小程序中:

在NetWork中可以看到接口的返回值:

图片上传成功;在后端也能看到图片已经保存下来了:

所有代码

前端代码

index.wxml:

bash 复制代码
<button type="primary" bind:tap="photoCapture">点击拍摄图片</button>
<image src="{{photoLink}}"></image>
<button type="primary" bind:tap="videoCapture">点击拍摄视频</button>
<image src="{{videoLink}}"></image>

index.wxss:

css 复制代码
page {
padding-top: 100rpx;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
}
image{
margin-top: 50rpx;
margin-bottom: 50rpx;
width: 600rpx;
height: 400rpx;
border: 1px solid black;
}

index.js:

vbnet 复制代码
Page({
data: {
photoLink: '',
videoLink: '',
},

//拍摄照片
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: res.data,
})
}
})
},
fail(res) {
console.log('图片拍摄失败')
}
})
},

//拍摄视频
videoCapture() {
let that = this
wx.chooseMedia({
count: 1,
mediaType: ['video'],
sourceType: ['camera'],
maxDuration: 60,
camera: 'back',
success(res) {
that.setData({
videoLink: res.tempFiles[0].thumbTempFilePath
})
console.log('视频拍摄成功')
console.log(res.tempFiles[0].tempFilePath)
wx.showLoading({
title: '正在上传视频',
mask: true
})

//视频上传
wx.uploadFile({
url:'http://localhost:5000/uploadVideo',
filePath: res.tempFiles[0].tempFilePath,
name: 'video',
formData: {
fileName:'videoTest.mp4'
},
success(res) {
wx.showToast({
title: res.data,
})
}
})
},
fail(res) {
console.log('图片拍摄失败')
}
})
}
})

后端代码

sql 复制代码
from flask import Flask, request
import os

app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello World'

@app.route('/uploadVideo', methods=["POST"])
def uploadVideo():
video = request.files['video'].stream.read()
name = request.form['fileName']
if not files_exists(name, 1):
file_path = os.getcwd() + '\videos\' + name
with open(file_path, 'ab') as f:
f.write(video)
return 'upload success'
else:
return 'already exist'


@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 'upload success'
else:
return '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)
相关推荐
在路上`1 分钟前
前端学习之后端java小白(三)-sql外键约束一对多
java·前端·学习
IT果果日记3 分钟前
详解DataX开发达梦数据库插件
大数据·数据库·后端
毕设源码-钟学长7 分钟前
【开题答辩全过程】以 基于微信小程序的美发服务系统的设计与实现为例,包含答辩的问题和答案
微信小程序·小程序
dazhong201210 分钟前
Spring Boot 项目新增 Module 完整指南
java·spring boot·后端
bobz96517 分钟前
Cilium + Kubevirt 与 Kube-OVN + Kubevirt 在公有云场景下的对比与选择
后端
Pu_Nine_91 小时前
10 分钟上手 ECharts:从“能跑”到“生产级”的完整踩坑之旅
前端·javascript·echarts·css3·html5
canglingyue1 小时前
微信小程序罗盘功能开发指南
微信小程序·小程序
David爱编程1 小时前
深度解析:synchronized 性能演进史,从 JDK1.6 到 JDK17
java·后端
東雪蓮☆2 小时前
从零开始掌握 Web 与 Nginx:入门详解
运维·服务器·前端·nginx
脑子慢且灵2 小时前
【JavaWeb】一个简单的Web浏览服务程序
java·前端·后端·servlet·tomcat·web·javaee