问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

微信小程序拍照上传功能最佳实践

创作时间:
2025-01-22 09:28:48
作者:
@小白创作中心

微信小程序拍照上传功能最佳实践

随着移动互联网的快速发展,微信小程序已成为开发者构建轻量级应用的重要平台。其中,拍照上传功能是许多小程序不可或缺的一部分,广泛应用于社交、电商、办公等多个场景。本文将详细介绍如何在微信小程序中实现高效稳定的拍照上传功能,从前后端代码实现到用户体验优化,全方位展示最佳实践方案。

01

基本功能实现

在微信小程序中实现拍照上传功能,主要涉及两个关键API:wx.chooseMediawx.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:仅在sourceTypecamera时生效,可选值为'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)
02

常见问题与解决方案

审核问题

在实际开发中,拍照上传功能可能会遇到微信小程序的审核问题。例如,有开发者反映即使明确表示不是人脸识别功能,仍然被要求使用人脸识别的原生接口。这可能与微信对隐私和安全的严格要求有关。建议在提交审核时详细描述功能用途,确保符合微信的相关政策。

上传速度慢

对于图片上传速度慢的问题,可以通过压缩图片来优化。例如,使用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);
        }
      });
    }
  });
}
03

用户体验优化

为了提升用户体验,可以考虑以下优化方案:

自动抓拍功能

在某些场景下,自动抓拍功能可以提供更便捷的用户体验。例如,使用<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对图片进行压缩可以显著提升上传速度,同时保持图片质量。

04

安全性与性能优化

在实现拍照上传功能时,还需要考虑安全性问题。例如,需要对上传的文件类型和大小进行限制,防止恶意文件上传。可以在后端代码中添加相应的检查逻辑:

@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传输等方式进一步提升安全性。

05

最佳实践总结

  1. 代码规范:确保前后端代码遵循良好的编程规范,使用清晰的变量命名和注释,便于维护和理解。

  2. 性能优化:使用图片压缩技术优化上传速度,同时考虑服务器的存储和处理能力,合理设置图片大小和分辨率。

  3. 用户体验:提供友好的用户界面和交互,如进度提示、错误处理和自动抓拍功能,提升用户满意度。

  4. 安全性:严格检查上传的文件类型和大小,使用HTTPS传输保护数据安全,防止恶意文件上传。

通过以上最佳实践,开发者可以实现一个既高效又安全的拍照上传功能,为用户提供优质的使用体验。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号