HarmonyOS Next 实战-基于鸿蒙Next模拟扫图识物的一个过程

71 阅读3分钟

一、功能介绍(基础)

基于鸿蒙Next模拟扫图识物的一个过程,扫描到图片,提示出相关的图片内容,是一个什么东西。

 

二、使用场景(大类)

 

支付、社交、信息获取、在线调查、教育学习等等。

 

三、实现步骤:

第一步:上传图片,打开相册时,会有获取媒体权限的弹窗询问。

第二部:扫一扫,识别图片内容。

第三步:识别到的图片信息展示,用弹窗的形式展现出来

 

四、展示效果

预览器效果

1.png

2.png

3.png

 

 

五、代码实现

import picker from '@ohos.file.picker'  
import common from '@ohos.app.ability.common'  
import promptAction from '@ohos.promptAction'  
  
let context = getContext(this) as common.UIAbilityContext  
  
  
let permissionList: Permissions[] = [  
  'ohos.permission.READ_MEDIA',  
  'ohos.permission.MEDIA_LOCATION'  
]  
  
@Entry  
@Component  
struct Index {  
  @State img:string = "/common/images/img_up.png" //初始化图片  
  @State scanHeight:number = 0 // 扫描高度-都动画  
  @State isVisibility:boolean = false // 扫描框显隐控制  
  
  //获取本地图片路径  
  getLocalPicPath() {  
    let photoPicker = new picker.PhotoViewPicker();  
    photoPicker.select({  
      MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE,  
      maxSelectNumber: 1  
    },  
      (err, photoPickerValue) => {  
        if (err) {  
          console.info("photoPicker_err:" + err.message)  
          return  
        }  
        console.info("photoPicker_Value:" + photoPickerValue.photoUris)  
        this.img = photoPickerValue.photoUris[0].toString()  
      }  
    )  
  }  
  
  //相册权限获取  
  isAuthorize() {  
    let AtManager = abilityAccessCtrl.createAtManager();  
    AtManager.requestPermissionsFromUser(context, permissionList)  
      .then((data) => {  
        console.info('request permissions from user success:' + data.authResults)  
        this.getLocalPicPath() //获取本地路径  
      })  
      .catch((err:Error) => {  
        console.info('request permissions from user failed:', JSON.stringify(err) ?? '')  
      });  
  }  
  
  //弹窗动画,识别图片内容  
  scanAnimation(){  
    let numT = 1  
    let timer = setInterval(()=>{  
      numT--  
      if (numT == 0){  
        this.isVisibility = false  
        this.scanHeight = 0  
      }  
      if (numT == -1){  
        promptAction.showDialog({  
          message:"键盘",  
          buttons:[  
            {  
              text:"确定",  
              color:"0x0091FF"  
            }  
          ]  
        })  
        clearInterval(timer)  
      }  
    },1000)  
  }  
  
  build(){  
    Column(){  
      //图片框  
      Stack(){  
        //上传图片框  
        Column(){  
          Image(this.img).width("100%").height("100%")  
        }.width(240)  
        .height(240)  
        .borderWidth(2)  
        .borderColor(0xB5E5FF)  
        .borderRadius(8)  
  
        //扫描框  
        Column(){  
        }.width(240)  
        .height(this.scanHeight)  
        .borderWidth({ bottom:1 })  
        .borderColor(0x0091FF)  
        .visibility(this.isVisibility ? Visibility.Visible:Visibility.Hidden)  
        .animation({  
          duration:1000,  
          tempo:1,  
          curve:Curve.Linear,  
          iterations:1,  
        })  
  
      }.width(245)  
      .height(245)  
      .alignContent(Alignment.Top)  
  
      //上传图片  
      Text("上传图片")  
        .width(120)  
        .height(40)  
        .fontSize(16)  
        .fontColor(0xffffff)  
        .fontWeight(600)  
        .borderRadius(4)  
        .textAlign(TextAlign.Center)  
        .stateStyles({  
          normal:{.backgroundColor(0x0091FF)},  
          pressed:{.backgroundColor(0x0091DD)}  
        })  
        .margin({top:20,bottom:10})  
        .onClick(()=>this.isAuthorize())  
  
      //扫一扫  
      Text("扫一扫")  
        .width(120)  
        .height(40)  
        .fontSize(16)  
        .fontColor(0xffffff)  
        .fontWeight(600)  
        .borderRadius(4)  
        .textAlign(TextAlign.Center)  
        .stateStyles({  
          normal:{.backgroundColor(0x0091FF)},  
          pressed:{.backgroundColor(0x0091DD)}  
        })  
        .onClick(()=>{  
          this.isVisibility = !this.isVisibility //控制扫描组件显隐  
          if (this.isVisibility) {  
            this.scanHeight = 240 // 高度等于stack组件高度  
            this.scanAnimation() //弹窗动画,识别图片内容  
          }else {  
            this.scanHeight = 0 // 高度等于0  
          }  
        })  
  
  
    }.height("100%")  
    .width("100%")  
    .justifyContent(FlexAlign.Center)  
    .alignItems(HorizontalAlign.Center)  
  }  
}

六、代码结构及原理:

1.整体结构:
使用了ArkTS的装饰器语法,如@Entry和@Component。
2.状态管理:
组件使用@State装饰器定义了几个响应式状态变量,如scanHeight、isVisibility。这些变量的变化会自动触发UI的更新。
3.UI结构:
界面使用嵌套的Stack、Column和Row组件构建。主要包括图形选择、线条颜色选择、线宽调节等部分。
4.数据传递:
当点击"上传图片"按钮时,会调用isAuthorize()回调函数,先获取媒体权限,确认授权之后,在调用getLocalPicPath()回调函数,获取选择的图片。点击“扫一扫”,识别上传图片内容

5.样式设置:
大量使用了链式调用来设置组件的样式,如字体大小、颜色、边距等。
6.响应式设计:
通过@State装饰器和状态变量的绑定,实现了界面的响应式更新。当用户进行操作时,相关的状态变量会更新,从而触发UI的重新渲染。