微信小程序camera相机帧转图片base64

适用于图像实时识别,形状识别,人脸识别等场景

相机组件

复制代码
        <camera class="camera-view" device-position="back" flash="off" binderror="onCameraError" bindinitdone="onCameraInit" frame-size="small">
            <!-- 扫描框 -->
            <view class="scan-frame"></view>
        </camera>

初始化相机

复制代码
   onCameraInit() {
        console.log('相机初始化完成');

        // 创建相机上下文
        this.cameraContext = wx.createCameraContext();

        // 获取系统信息判断平台
        const systemInfo = wx.getSystemInfoSync();
        const isIOS = systemInfo.platform === 'ios';

        let lastTime = 0;
        const interval = 3000; // 每3秒取一帧

        try {
            this.frameListener = this.cameraContext.onCameraFrame((frame) => {
                const now = Date.now();
                if (now - lastTime < interval) return; // 跳过多余帧
                lastTime = now;

                if (!frame || !frame.data || frame.data.byteLength === 0) {
                    console.warn('帧数据为空或无效');
                    return;
                }

                console.log('取到一帧', frame.width, frame.height, frame.data.byteLength);

                // 转成图片 base64
                this.frameToBase64(frame).then((base64: string) => {
                    // 调用识别 API
                    this.recognizeFrameData(base64, frame.width, frame.height);
                }).catch((error: any) => {
                    console.error('frameToBase64 转换失败:', error);
                });
            });

            // iOS 使用 worker,Android 不使用
            if (isIOS) {
                try {
                    this.worker = wx.createWorker('workers/cameraWorker.js', {
                        useExperimentalWorker: true
                    });
                    this.frameListener.start({ worker: this.worker });
                } catch (error) {
                    console.error('创建 Worker 失败,使用普通模式:', error);
                    this.frameListener.start();
                }
            } else {
                this.frameListener.start();
            }

            console.log('相机帧监听器已启动');
        } catch (error) {
            console.error('启动相机帧监听失败:', error);
        }


    },

注意ios要使用workers

相关代码

复制代码
// workers/cameraWorker.js
setInterval(() => {
  try {
    const frameData = worker.getCameraFrameData(); // ArrayBuffer
    if (frameData.byteLength === 0) return;

    // base64 转换
    const base64 = wx.arrayBufferToBase64(frameData);
    console.log('iOS 帧 base64 长度', base64.length);

    // 可以 postMessage 给主线程做处理
    worker.postMessage({ base64 });
  } catch (err) {
    console.error(err);
  }
}, 1000); // 每秒处理一帧

这里直接获取的帧需要转换成图片base64,为什么要转?

小程序相机每一帧给的是 原始 RGBA 像素数据,并不能直接使用,而是需要转换。

目前的方案是创建一个canvas将图片像素图绘制上去,然后再把 canvas 内容 转成 Base64 格式的 JPEG。

复制代码
   frameToBase64(frame: any): Promise<string> {
        return new Promise((resolve, reject) => {
            try {
                // 创建离屏 canvas
                const canvas = wx.createOffscreenCanvas({ 
                    type: '2d',
                    width: frame.width, 
                    height: frame.height 
                });
                
                const ctx = canvas.getContext('2d');
                
                if (!ctx) {
                    reject(new Error('Failed to get canvas context'));
                    return;
                }

                // 创建 ImageData 对象
                const imageData = ctx.createImageData(frame.width, frame.height);
                
                // 将帧数据复制到 ImageData
                const data = new Uint8Array(frame.data);
                imageData.data.set(data);
                
                // 将 ImageData 绘制到 canvas
                ctx.putImageData(imageData, 0, 0);
                
                // 转为 base64 - 使用同步方式
                try {
                    const base64 = canvas.toDataURL({
                        type: 'image/jpeg',
                        quality: 0.8
                    });
                    resolve(base64);
                } catch (e) {
                    reject(e);
                }
            } catch (error) {
                reject(error);
            }
        });
    },
相关推荐
QuantumLeap丶2 小时前
《uni-app跨平台开发完全指南》- 05 - 基础组件使用
vue.js·微信小程序·uni-app
发财北3 小时前
全屋智能家居定制小程序
小程序
2501_915918414 小时前
Flutter 加固方案对比与实战,多工具组合的跨平台安全体系(Flutter App 加固/IPA 成品混淆/Ipa Guard CLI/自动化安全流程)
安全·flutter·ios·小程序·uni-app·自动化·iphone
泽_浪里白条4 小时前
UniApp + Vue3 开发微信小程序数字人:TTS PCM 音频流与 SVGA 动画同步实战
微信小程序
小蒜学长4 小时前
springboot基于Java的校园导航微信小程序的设计与实现(代码+数据库+LW)
java·spring boot·后端·微信小程序
说私域5 小时前
定制开发AI智能名片S2B2C商城小程序的发展与整合资源策略研究
人工智能·小程序
WenGyyyL6 小时前
微信小程序开发——第二章:微信小程序开发环境搭建
开发语言·python·微信小程序
TiAmo zhang6 小时前
微信小程序开发案例 | 个人相册小程序(上)
微信小程序·小程序
00后程序员张19 小时前
iOS 上架费用全解析 开发者账号、App 审核、工具使用与开心上架(Appuploader)免 Mac 成本优化指南
android·macos·ios·小程序·uni-app·cocoa·iphone