微信小程序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);
            }
        });
    },
相关推荐
计算机毕设指导62 天前
基于微信小程序的校园食堂点餐系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·intellij-idea
项目題供诗2 天前
微信小程序黑马优购(项目)(八)
微信小程序·小程序
2501_915918412 天前
iOS 项目中证书管理常见的协作问题
android·ios·小程序·https·uni-app·iphone·webview
2501_915918412 天前
提升 iOS 应用安全审核通过率的一种思路,把容易被拒的点先处理
android·安全·ios·小程序·uni-app·iphone·webview
00后程序员张2 天前
APP如何快速上架Apple Store:完整上架流程与常见问题解析
android·小程序·https·uni-app·iphone·webview
Chloe.Zz2 天前
微信小程序接入大模型实战 4:塔罗咨询室(含代码)
语言模型·微信小程序·小程序
2501_916008892 天前
iOS 应用发布流程中常被忽视的关键环节
android·ios·小程序·https·uni-app·iphone·webview
Q_Q5110082852 天前
小程序基于Java Web的健身房管理系统设计和开发
java·前端·小程序
艾上编程2 天前
第四章——桌面小程序场景之使用Tkinter制作文件格式转换器:满足日常格式转换需求
开发语言·小程序
风月歌2 天前
小程序项目之“健康早知道”微信小程序源码(java+小程序+mysql)
java·微信小程序·小程序·毕业设计·源码