鸿蒙next 带你玩转Web组件拉起相机进行拍照

382 阅读2分钟

前言导读

在鸿蒙next项目开发中,是不是经常会碰到跟h5交互 ,甚至还有直接在网友里面加载的图片 ,那么今天我们就分享给 各位一个案例 Web组件拉起相机进行拍照 然后显示在我们网页上面

效果图

64f8909c66401427e137a7fe94b4deef[00_00_00--00_00_20].gif

具体实现

  • 声明 WebviewController
controller: web_webview.WebviewController = new web_webview.WebviewController();
  • 加载我们本地html
Column() {
  Web({ src: $rawfile("camera.html"), controller: this.controller })

    .margin({ top: 40 })
    .backgroundColor(Color.Black)
}
.backgroundColor(Color.Black)
  • 资源存放在我们 resources下面的rawfile目录下面

image.png

定义FileResult model

class FileResult {
  result: FileSelectorResult;
  fileSelector: FileSelectorParam;

  constructor(result: FileSelectorResult, fileSelector: FileSelectorParam) {
    this.result = result;
    this.fileSelector = fileSelector;
  }
}
  • 实现 onShowFileSelector 方法

我们实现 onShowFileSelector方法并将我们的FileResult 对象传入

Web({ src: $rawfile("camera.html"), controller: this.controller })
  .onShowFileSelector((event: FileResult) => {
    this.invokeCamera(((uri: string) => {
      event?.result.handleFileList([uri]);
    }))
    return true;
  })
  .margin({ top: 40 })
  .backgroundColor(Color.Black)
  • 打开相机逻辑

invokeCamera(callback: (uri: string) => void) {
  const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  const want: Want = {
    action: "ohos.want.action.imageCapture",
    parameters: {
      'callBundleName': context.abilityInfo.bundleName,
    }
  };
  const result: (error: BusinessError, data: common.AbilityResult) => void = (error: BusinessError,
    data: common.AbilityResult) => {
    const resultUri: string = data.want?.parameters?.resourceUri as string;
    if (callback && resultUri) {
      callback(resultUri);
    }
  }
  context.startAbilityForResult(want, result);
}

完整代码



import web_webview from '@ohos.web.webview';
import { common, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';




class FileResult {
  result: FileSelectorResult;
  fileSelector: FileSelectorParam;

  constructor(result: FileSelectorResult, fileSelector: FileSelectorParam) {
    this.result = result;
    this.fileSelector = fileSelector;
  }
}

@Entry
@Component
struct Index {
  controller: web_webview.WebviewController = new web_webview.WebviewController();

  build() {
    Column() {
      Web({ src: $rawfile("camera.html"), controller: this.controller })
        .onShowFileSelector((event: FileResult) => {
          this.invokeCamera(((uri: string) => {
            event?.result.handleFileList([uri]);
          }))
          return true;
        })
        .margin({ top: 40 })
        .backgroundColor(Color.Black)
    }
    .backgroundColor(Color.Black)
  }


  invokeCamera(callback: (uri: string) => void) {
    const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
    const want: Want = {
      action: "ohos.want.action.imageCapture",
      parameters: {
        'callBundleName': context.abilityInfo.bundleName,
      }
    };
    const result: (error: BusinessError, data: common.AbilityResult) => void = (error: BusinessError,
      data: common.AbilityResult) => {
      const resultUri: string = data.want?.parameters?.resourceUri as string;
      if (callback && resultUri) {
        callback(resultUri);
      }
    }
    context.startAbilityForResult(want, result);
  }
}

html代码

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8">
    <style>
        body {
          font-family: Arial, Helvetica, sans-serif, sans-serif;
          text-align: center;
          background-color: #000000;
          margin: 0;
        }
        #image {
          display: none;
          width: 100%;
          height: auto;
          padding-top: 50px;
        }
        #image_preview {
          display: none;
          margin-top: 15px;
        }
        .a-upload {
          text-decoration:none;
          padding: 10px 20px;
          height: 20px;
          line-height: 20px;
          position: relative;
          cursor: pointer;
          color: #ffffff;
          background-color: rgb(10, 89, 247);
          border-radius: 20px;
          overflow: hidden;
          display: inline-block;
          *display: inline;
          *zoom: 1
        }
        .a-upload  input {
            position: absolute;
            font-size: 100px;
            right: 0;
            top: 0;
            opacity: 0;
            filter: alpha(opacity=0);
            cursor: pointer
            border-radius: 20px;
            background: rgb(10, 89, 247);
        }
         .upload-button {
             padding: 6px 25px;
             background: #00bfff;
             border-radius: 4px;
             color: white;
             cursor: pointer;
             }
    </style>
</head>

<body>
<script>
    function showPic() {
      let event = this.event;
      let tFile = event ? event.target.files : [];
      if (tFile === 0) {
        document.getElementById('image_preview').style.display = 'block';
        document.getElementById('image_preview').innerHTML = "未选择图片";
        return;
      }
      document.getElementById('image').setAttribute('src', URL.createObjectURL(tFile[0]));
      document.getElementById('image_preview').style.display = 'block';
      document.getElementById('image').style.display = 'block';
    }
</script>

<a href="javascript:;" class="a-upload" id="a_upload">
    <label class="input-file-button" for="upload">相机</label>
    <input type="file" id="upload" name="upload" accept="image/*" capture="upload" onchange="showPic()"/>
</a>
<p id="image_preview"></p>
<img id="image">
</body>

</html>

网页效果

image.png

最后总结

Web组件拉起相机进行拍照然后显示再网页上面 我们主要还是通过原生的代码去打开相机拍照后然后拿到图片的uri 后再去回调通知给html然后显示再我们的网页上面。更多的实用场景,各位同学可以拷贝代码去进行改造,今天的文章就分享到这里。我们下一期再见。今天的文章就讲到这里有兴趣的 关注我B站教程 了解更多鸿蒙开发的知识 可以关注我的B站课程