前置准备

imageKnife安装:

ohpm install @ohos/imageknife

imageKnife请求网络gif的时,需要开通网络权限,在使用imageknife的模块module.json5中添加网络权限:

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET",
    "usedScene": {
      "abilities": [
        "EntryAbility"
      ],
      "when": "always"
    }
  }]

在项目内初始化ImageKnifeOption,配置请求头和加载图片的基本参数:

@State option: ImageKnifeOption = {
  loadSrc: $r('app.media.startIcon'),//resources资源加载,默认icon
  headerOption: [{
    key: "refer",
    value: "https://1.94.37.200:7070/AntiTheftChain/downloadImage"
  }],//请求头
  placeholderSrc: $r('app.media.icon_loading'),//加载中显示loading图
  errorholderSrc: $r('app.media.icon_failed')//加载失败图
}

然后将加载好的数据传给ImageKnifeComponent,一个默认的样式就写好了。

ImageKnifeComponent({ imageKnifeOption: this.option })

场景

场景一:imageKnife可以实现控制gif图片的播放次数与帧数的定格

核心代码

实例化ImageKnifeOption后,添加gif属性,将字段playTime设置传入播放的次数,即可完成播放次数的控制。

Button("播放")
  .onClick(() => {
    this.option = {
      loadSrc: 'https://xxx.gif',
      placeholderSrc: $r('app.media.icon_loading'),
      errorholderSrc: $r('app.media.icon_failed'),
      displayProgress: true,
      gif: {
        playTimes: this.times
      }
    }
  }).margin({ top: 20 })

添加gif属性,将字段seekTo设置传入要定格的帧数,即可完成定格帧数。

Button("定格帧数")
  .onClick(() => {
    this.option = {
      loadSrc: 'https://xxx.gif',
      placeholderSrc: $r('app.media.icon_loading'),
      errorholderSrc: $r('app.media.icon_failed'),
      displayProgress: true,
      gif: {
        seekTo: this.stop
      }
    }
  })

场景二:imageKnife实现播放和暂停gif的功能

核心代码

实例化ImageKnifeOption后,设置autoplay图片属性true/false,完成gif的暂停和继续播放。

Button('暂停图片').onClick(() => {
  this.option.autoPlay = false;
})

Button('播放图片').onClick(() => {
  this.option.autoPlay = true;
})

场景三:imageKnife对于网络环境和本地的加载的方式

核心代码

实例化ImageKnifeOption后,将索引传入对应的点击事件,分别加载本地资源和网络资源。

  • 本地资源格式:loadSrc:$r('app.media.gifSample')。
  • 网络资源格式:oadSrc = 'https://xxxx.gif'。
Select([
  { value: '资源加载', },
  { value: '网络加载', },
  { value: '图库加载(待定)', },
])
  .selected(this.index)
  .value(this.text)
  .font({ size: 16, weight: 500 })
  .fontColor('#182431')
  .selectedOptionFont({ size: 16, weight: 400 })
  .optionFont({ size: 16, weight: 400 })
  .space(this.space)
  .arrowPosition(this.arrowPosition)
  .menuAlign(MenuAlignType.START, { dx: 0, dy: 0 })
  .optionWidth(200)
  .optionHeight(300)
  .onSelect((index: number, text?: string | undefined) => {
    console.info('Select:' + index)
    this.index = index;//传入点击事件 完成判断加载网络gif还是本地
    index == 0 ? this.option.loadSrc = $r('app.media.gifSample'):this.option.loadSrc = 'https://xxx.gif'
    if (text) {
      this.text = text;
    }
  })

场景四:imageKnife对于gif样式边框的设置,包括边框的宽度,颜色,圆角

核心代码

实例化ImageKnifeOption后,将设置好的参数传入drawLifeCycle: ImageKnifeDrawFactory.createRoundLifeCycle,实现边框效果的转换。

Text("gif设置边框效果").fontSize(25)
TextInput({ placeholder: '圆角宽度' }).margin({ top: 20 }).width('50%').type(InputType.Number)
  .onChange((value: string) => {
    this.BorderWidth = Number(value)
  })
TextInput({ placeholder: '颜色样例:#ff0000' })
  .type(InputType.Normal)
  .margin({ top: 20 })
  .width('50%')
  .onChange((value: string) => {
    this.colorString = value
  })
TextInput({ placeholder: '圆角弧度' })
  .type(InputType.Number)
  .margin({ top: 20 })
  .width('50%')
  .onChange((value: string) => {
    this.connerRadius = Number(value)
  })
Button("网络gif - 设置参数").onClick(() => {
  this.option = {
    loadSrc: 'https://xxx.gif',
    drawLifeCycle: ImageKnifeDrawFactory.createRoundLifeCycle(this.BorderWidth, this.colorString, this.BorderWidth)
  }

场景五:imageKnife获取gif图片的基本信息,包括宽度,高度,帧率,总帧数

核心代码

<p id="p18102163113915">接口</p> <p id="p2102731395">参数</p> <p id="p31023314919">说明</p>
<p id="p36272042994">addListener(func: AsyncCallback)</p> <p id="p141020312098">func: AsyncCallback</p> <p id="p91021931795">配置整个监听回调,数据正常加载返回,加载失败返回错误信息</p>

实例化ImageKnifeOption后,先实例化网络请求new RequestOption(),load加载gif链接,添加监听属性addListener,回调返回拿到对象的width,height,delay。

因为gif动图本质是一个播放,所以将每次拿到的帧数相加可以得到总帧数(max),经过for循环找到循环的次数maxtimes,再用总帧数除以次数得到每秒帧率avg。

Button('预加载网络资源gif')
  .onClick(() => {
    let request = new RequestOption();
    request.load('https://xxx.gif')
      .setImageViewSize({ width: 300, height: 300 })
      .addListener({
        callback: (err: BusinessError | string, data: ImageKnifeData) => {
          if (err) {
            console.log('预加载网络资源gif 出现错误! err=' + err)
          } else {
            console.log('预加载网络资源gif成功! imageKnifedata=' + JSON.stringify(data.drawGIFFrame?.imageGIFFrames![0].dims.width))
            console.log('预加载网络资源gif成功! imageKnifedata=' + JSON.stringify(data.drawGIFFrame?.imageGIFFrames))
            this.Width = data.drawGIFFrame?.imageGIFFrames![0].dims.width
            this.Height = data.drawGIFFrame?.imageGIFFrames![0].dims.height
            for (let i = 0; i < ((data.drawGIFFrame?.imageGIFFrames!).length); i++) {
              this.max += Number(data.drawGIFFrame?.imageGIFFrames![i].delay)
              console.log("预加载网络资源gif成功! max=" + this.max)
              this.maxtimes = i
              console.log("预加载网络资源gif成功! maxtimes=" + this.maxtimes)
            }
            this.avg = this.max / this.maxtimes
            console.log("预加载网络资源gif成功! avg=" + this.avg)
          }
          return false;
        }
      })
    ImageKnifeGlobal.getInstance().getImageKnife()?.preload(request);
  })

注意:

  1. 加载网络请求的和本地格式要注意区分。
  2. 添加权限后要配置ImageKnifeOption的请求头。

HarmonyOS码上奇行
7k 声望2.8k 粉丝