微信小程序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);
            }
        });
    },
相关推荐
我命由我1234515 分钟前
微信开发者工具 - 模拟器分离窗口与关闭分离窗口
前端·javascript·学习·微信小程序·前端框架·html·js
G佳伟6 小时前
‌微信小程序Webview转发页面空白问题解决方案‌
微信小程序·小程序
vx_vxbs668 小时前
【SSM电动车智能充电服务平台】(免费领源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
java·spring boot·mysql·spring cloud·小程序·php·idea
小皮虾9 小时前
告别服务器!小程序纯前端“图片转 PDF”工具,隐私安全又高效
前端·javascript·微信小程序
低代码布道师10 小时前
医疗小程序12出诊列表
低代码·小程序
Coder-coco11 小时前
游戏助手|游戏攻略|基于SprinBoot+vue的游戏攻略系统小程序(源码+数据库+文档)
java·vue.js·spring boot·游戏·小程序·论文·游戏助手
小小王app小程序开发1 天前
盲盒小程序一番赏衍生玩法:魔王赏、非酋赏、狂欢赏差异化分析
小程序
2501_915106321 天前
iOS App 测试工具全景分析,构建从开发调试到线上监控的多阶段工具链体系
android·测试工具·ios·小程序·uni-app·iphone·webview
头发还在的女程序员2 天前
基于JAVA语言的短剧小程序-抖音短剧小程序
java·开发语言·小程序
2501_916007472 天前
iOS 应用性能测试的工程化流程,构建从指标采集到问题归因的多工具协同测试体系
android·ios·小程序·https·uni-app·iphone·webview