基于imageKnife对gif图的管理

幸运小面
发布于 2024-8-1 16:37
浏览
0收藏

前置准备

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图片的基本信息,包括宽度,高度,帧率,总帧数

核心代码

接口

参数

说明

addListener(func: AsyncCallback)

func: AsyncCallback

配置整个监听回调,数据正常加载返回,加载失败返回错误信息


实例化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的请求头。

分类
已于2024-8-1 16:37:57修改
收藏
回复
举报
回复
    相关推荐