HarmonyOS 鸿蒙Next Web组件调用相机拍照 鸿蒙场景化代码

发布于 1周前 作者 bupafengyu 来自 鸿蒙OS

HarmonyOS 鸿蒙Next Web组件调用相机拍照 鸿蒙场景化代码
<markdown _ngcontent-ywi-c147="" class="markdownPreContainer">

Web组件调用相机拍照

介绍

本示例演示如何使用Web组件拍照和录音。

  1. web拉起系统相机拍照,并返回base64数据给web页面。
  2. web调用麦克风录音,并保持录音文件到指定沙箱目录。

Web组件调用相机拍照源码链接

效果图

图片名称

使用说明

  1. web调用相机拍照:
    1. 打开应用后,点击“拍照按钮”
    2. 在拉起的系统相机中进行拍照
    3. 拍照完成后web网页会获取到base64数据
  2. web调用麦克风录音:
    1. 打开应用后,点击“开始录音”
    2. 一段时间后,点击“结束录音”
    3. 录音完成后录音文件保存在沙箱目录下,文件名为Audio_录音时间.mp4

实现思路

web调用相机拍照

点击拍照按钮后,应用通过@ohos.app.ability.Want接口拉起系统相机进行拍照,并获取图片uri值。通过图片uri值转为ArrayBuff,使用@ohos.file.fs接口读取文件数据,通过Base64Helper接口将文件转化为base64数据返回给web网页。核心代码如下,源码参考

WebPage.ets

深色代码主题
复制
async getCamera():Promise<string> {
    let want: Want = {
      action: 'ohos.want.action.imageCapture',
      parameters: {
        // 拍照完成后返回的应用BundleName
        callBundleName: 'com.example.webdemos',
        supportMultiMode: false
      }
    };
    try {
      let result:common.AbilityResult = await this.context.startAbilityForResult(want)
  <span class="hljs-variable language_">this</span>.<span class="hljs-property">uri</span> = result?.<span class="hljs-property">want</span>?.<span class="hljs-property">parameters</span>?.<span class="hljs-property">resourceUri</span> <span class="hljs-keyword">as</span> string;
} <span class="hljs-keyword">catch</span> (err) {
  <span class="hljs-keyword">let</span> error = err <span class="hljs-keyword">as</span> <span class="hljs-title class_">BusinessError</span>;
  <span class="hljs-title class_">LoggerUtil</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">`startAbilityForResult failed, err is <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(error)}</span>`</span>);
}

<span class="hljs-keyword">if</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">uri</span> !== <span class="hljs-string">''</span>){
  <span class="hljs-comment">//转为base64</span>
  <span class="hljs-keyword">let</span> base64 = <span class="hljs-keyword">await</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">loadImage</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">uri</span>)
  <span class="hljs-keyword">return</span> base64
}
<span class="hljs-keyword">return</span> <span class="hljs-string">''</span>

}

async loadImage(uri: string):Promise<string>{ let f = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY);

<span class="hljs-keyword">let</span> photoSize = fileIo.<span class="hljs-title function_">statSync</span>(f.<span class="hljs-property">fd</span>).<span class="hljs-property">size</span>;
<span class="hljs-title class_">LoggerUtil</span>.<span class="hljs-title function_">info</span>(<span class="hljs-string">'Photo Size: '</span> + photoSize);
<span class="hljs-keyword">let</span> buffer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayBuffer</span>(photoSize);
fileIo.<span class="hljs-title function_">readSync</span>(f.<span class="hljs-property">fd</span>, buffer);
fileIo.<span class="hljs-title function_">closeSync</span>(f);

<span class="hljs-keyword">let</span> base64 = <span class="hljs-keyword">new</span> util.<span class="hljs-title class_">Base64Helper</span>(); <span class="hljs-comment">// 实例化Base64Helper</span>
<span class="hljs-keyword">let</span> unit8data = base64.<span class="hljs-title function_">encodeSync</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Uint8Array</span>(buffer.<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, buffer.<span class="hljs-property">byteLength</span>))) <span class="hljs-comment">// 转换成Uint8Array</span>
<span class="hljs-title class_">LoggerUtil</span>.<span class="hljs-title function_">info</span>(<span class="hljs-string">`data长度:<span class="hljs-subst">${unit8data.length}</span>`</span>)
<span class="hljs-keyword">let</span> textDecoder = util.<span class="hljs-property">TextDecoder</span>.<span class="hljs-title function_">create</span>(<span class="hljs-string">'utf-8'</span>, { ignoreBOM : <span class="hljs-literal">true</span> })
<span class="hljs-keyword">let</span> retStr = textDecoder.<span class="hljs-title function_">decodeToString</span>( unit8data , {<span class="hljs-attr">stream</span>: <span class="hljs-literal">false</span>}); <span class="hljs-comment">// 可以把Uint8Array转码成base64</span>
<span class="hljs-keyword">return</span> retStr;

}

web调用麦克风录音

使用@ohos.multimedia.media接口的AVRecorder方法进行音频录制,调用该方法前,需要先通过createAVRecorder()构建一个AVRecorder实例。使用AVRecorderConfig方法进行音频录制的参数设置,此处为纯音频录制,因此仅需要设置audioSourceType。核心代码如下,源码参考

AudioRecorder.ets

深色代码主题
复制
private avConfig: media.AVRecorderConfig = {
    audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC, // 音频输入源,这里设置为麦克风
    profile: this.avProfile,
    url: '', // 参考应用文件访问与管理开发示例新建并读写一个文件
  };
  textTimerController: TextTimerController = new TextTimerController()
  async startRecordingProcess(firDir:string) {
    this.savDir = firDir
    try {
      if (this.avRecorder == undefined) {
        // 1.创建录制实例
        this.avRecorder = await media.createAVRecorder();
      }
      this.setAudioRecorderCallback();
      // 2.获取录制文件fd赋予avConfig里的url;参考FilePicker文档
      this.curFile = fileIo.openSync(firDir, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
      this.avConfig.url = 'fd://' + this.curFile.fd;
      // 3.配置录制参数完成准备工作
      await this.avRecorder.prepare(this.avConfig);
      // 4.开始录制
      this.textTimerController.start()
      await this.avRecorder.start();
    } catch (err) {
      Logger.info('startRecordingProcess' + JSON.stringify(err))
    }
  }

工程结构&模块类型

深色代码主题
复制
│──entry/src/main/ets  // 应用主包,hap包
│  ├──entryability
│  │  └──EntryAbility.ts          // 程序入口类
│  ├──pages
│  │  └──Index.ets              // 闪屏页
      └── WebPage.ets        // web操作页
│  ├──utils
│  │  └──AudioRecorder.ets      // 录音工具类
      └── LoggerUtil.ets        // 日志类
│──entry/src/main/resources  // 资源文件
│  ├──rawfile
│  │  └──index.html          // 样例web页文件

模块依赖

参考资料

</markdown>

更多关于HarmonyOS 鸿蒙Next Web组件调用相机拍照 鸿蒙场景化代码的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next Web组件调用相机拍照 鸿蒙场景化代码的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS(鸿蒙)系统中,Next Web组件调用相机拍照的场景化代码主要依赖于鸿蒙提供的相机能力和ArkUI框架。以下是一个简化的示例代码,展示如何在ArkUI中使用相机拍照功能:

// 在页面的.ets文件中
@Entry
@Component
struct CameraDemo {
  @State cameraAbility: any = null;

  startCamera() {
    media.createCameraContext({
      success: (context) => {
        this.cameraAbility = context;
        this.cameraAbility.takePhoto({
          success: (data) => {
            console.log('Photo taken:', data.photo);
          },
          fail: (err) => {
            console.error('Failed to take photo:', err);
          }
        });
      },
      fail: (err) => {
        console.error('Failed to create camera context:', err);
      }
    });
  }

  build() {
    Column() {
      Button('Start Camera')
        .onClick(() => this.startCamera());
    }.padding(20);
  }
}

上述代码创建了一个简单的按钮,点击后尝试启动相机并拍照。注意,实际应用中可能需要处理更多细节,如权限请求、UI布局优化等。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部