基础ArkTS组件:图片(HarmonyOS学习第三课【3.2】)

图片组件

Image为图片组件,常用于在应用中显示图片。Image支持加载string、PixelMapResource类型的数据源,支持png、jpg、bmp、svg和gif类型的图片格式。

需要权限

使用网络图片时,需要申请权限ohos.permission.INTERNET。具体申请方式请参考权限申请声明

子组件

接口

Image(src: string | PixelMap | Resource)

通过图片数据源获取图片,用于后续渲染展示。

Image组件加载图片失败或图片尺寸为0时,图片组件大小自动为0,不跟随父组件的布局约束。

从API version 9开始,该接口支持在ArkTS卡片中使用。

Image定义介绍

interface ImageInterface {
  (src: string | PixelMap | Resource): ImageAttribute;
}
  • src:设置要加载的图片资源,支持从本地、网络和内存中加载图片,简单样例如下:

     Flex() {
              Image($r("app.media.fanhui"))
                .width('30')
                .margin({ top: 10 });
            }.width("100%")
    
            Flex() {
              Image($r("app.media.xiaoxi"))
                .width('120')
                .margin({ top: 10 });
            }.offset({ x: "120vp" })

                  

Image属性介绍:

declare class ImageAttribute extends CommonMethod<ImageAttribute> {
  alt(value: string | Resource): ImageAttribute;
  matchTextDirection(value: boolean): ImageAttribute;
  fitOriginalSize(value: boolean): ImageAttribute;
  fillColor(value: ResourceColor): ImageAttribute;
  objectFit(value: ImageFit): ImageAttribute;
  objectRepeat(value: ImageRepeat): ImageAttribute;
  autoResize(value: boolean): ImageAttribute;
  renderMode(value: ImageRenderMode): ImageAttribute;
  interpolation(value: ImageInterpolation): ImageAttribute;
  sourceSize(value: { width: number; height: number }): ImageAttribute;
  syncLoad(value: boolean): ImageAttribute;
  onComplete(
    callback: (event?: {
      width: number;
      height: number;
      componentWidth: number;
      componentHeight: number;
      loadingStatus: number;
    }) => void,
  ): ImageAttribute;
  onError(callback: (event?: { componentWidth: number; componentHeight: number }) => void): ImageAttribute;
  onFinish(event: () => void): ImageAttribute;
}
  • alt:设置占位图,图片显示之前先显示占位图,比如在加载网络图片或者图片加载失败时的场景。

  • objectFit:设置图片的放缩类型,当 Image 组件大小和图片大小不同时指定图片的放缩类型, ImageFit 提供了以下5种匹配模式:

    • Cover(默认值):保持图片宽高比进行放缩显示,使得图片完全显示在显示边界外。

    • Contain:保持图片宽高比进行放缩显示,使得图片完全显示在显示边界内。

    • Fill:不保持图片宽高比显示,是图片完全充满显示边界。

    • None:保持图片原有尺寸显示,通常配合 objectRepeat 属性一起使用。

    • ScaleDown:保持图片宽高比显示,使图片缩小或者保持不变的显示出来。

以上6中匹配模式运行结果如下图所示:

                                     

renderMode:设置图片的渲染模式, ImageRenderMode 定义了以下2种渲染模式:

  • Original(默认值):按照原图进行渲染。

  • Template:将图像渲染为模板图像,忽略图片的颜色信息。

代码:

          Image($r("app.media.xiaoxi"))
            .width(90)
            .height(90)
            .renderMode(ImageRenderMode.Original) // 原图渲染

          Image($r("app.media.xiaoxi"))
            .width(90)
            .height(90)
            .renderMode(ImageRenderMode.Template) // 模板渲染

                  

sourceSize:对原始图片做部分解码,样例如下:

Image($r("app.media.xiaoxi"))
  .width(90)
  .height(90)

Image($r("app.media.xiaoxi"))
  .width(90)
  .height(90)
  .sourceSize({width: 10, height: 10}) // 设置解码的宽高

                     

Image事件介绍

declare class ImageAttribute extends CommonMethod<ImageAttribute> {
  onComplete(
    callback: (event?: {
      width: number;
      height: number;
      componentWidth: number;
      componentHeight: number;
      loadingStatus: number;
    }) => void,
  ): ImageAttribute;
  onError(callback: (event?: { componentWidth: number; componentHeight: number }) => void): ImageAttribute;
  onFinish(event: () => void): ImageAttribute;
}
  • onComplete:图片成功加载时触发该回调,返回图片原始尺寸信息。
  • onError:图片加载出现异常时触发该回调。
  • onFinish:当加载的源文件为带动效的 svg 图片时,当 svg 动效播放完成时会触发这个回调,如果动效为无限循环动效,则不会触发这个回调。

Image加载方式

  • 从本地加载

    • 拷贝 test.png 图片到工程的 resources/main/base/media 目录下

    • 加载图片,直接使用系统提供的资源访问符 $() 或者本地文件加载

      import image from '@ohos.multimedia.image';
      import file from '@ohos.fileio';
      
      @Entry @Component struct ComponentTest {
      
        @State pixelMap: PixelMap = undefined;
      
        build() {
          Column() {
            if (undefined == this.pixelMap) {
              Image($r("app.media.test"))
              	.width(180)
      				  .height(80)
            } else {
              Image(this.pixelMap)
              	.width(180)
      				  .height(80)
            }
          }
          .alignItems(HorizontalAlign.Center)
          .width('100%')
          .height(('100%'))
          .padding(10)
        }
      
        private aboutToAppear() {
          var fd = file.openSync("/data/imgs/test.png");
          image.createImageSource(fd).createPixelMap({
            sampleSize: 1,
            rotate: 0,
            editable: false
          }).then((pixelMap) => {
            this.pixelMap = pixelMap;
          })
        }
      }
      
  • 从网络加载

    Image('https://img.sample.com/imgs/test.png')
      .width(180)
      .height(80)
    
  • 从内存加载

    Image(this.pixelMap) // pixelMap为内存图片
      .width(180)
      .height(80)
    

Image缓存设置

Image 组件没有提供图片缓存相关的 api ,ArkUI开发框架在 @system.app 模块内提供了图片的全局缓存策略,全局缓存策略使用了 LRU 算法:

  • setImageCacheCount:设置内存中缓存解码后图片的数量上限,单位为 number。

  • setImageRawDataCacheSize:设置内存中缓存解码前图片数据的大小上限,单位为字节。

  • setImageFileCacheSize:设置图片文件缓存的大小上限,单位为字节。

    在APP启动的时候,设置全局缓存策略,用法如下:

    import app from '@system.app';
    
    export default {
      onCreate() {
        console.info('Application onCreate')
        app.setImageRawDataCacheSize(100 * 1024 * 1024) // 设置解码前图片数据内存缓存上限为100MB
      },
      onDestroy() {
        console.info('Application onDestroy')
      },
    }

官方示例

加载基本类型图片

@Entry
@Component
struct ImageExample1 {
  build() {
    Column() {
      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
        Row() {
          // 加载png格式图片
          Image($r('app.media.ic_camera_master_ai_leaf'))
            .width(110).height(110).margin(15)
            .overlay('png', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
          // 加载gif格式图片
          Image($r('app.media.loading'))
            .width(110).height(110).margin(15)
            .overlay('gif', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        }
        Row() {
          // 加载svg格式图片
          Image($r('app.media.ic_camera_master_ai_clouded'))
            .width(110).height(110).margin(15)
            .overlay('svg', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
          // 加载jpg格式图片
          Image($r('app.media.ic_public_favor_filled'))
            .width(110).height(110).margin(15)
            .overlay('jpg', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        }
      }
    }.height(320).width(360).padding({ right: 10, top: 10 })
  }
}

                              

加载网络图片

加载网络图片时,默认网络超时是5分钟,建议使用alt配置加载时的占位图。如果需要更灵活的网络配置,可以使用SDKHTTP工具包发送网络请求,接着将返回的数据解码为Image组件中的PixelMap

使用网络图片时,需要申请权限ohos.permission.INTERNET。具体申请方式请参考权限申请声明

@Entry
@Component
struct ImageExample2 {
  build() {
    Column({ space: 10 }) {
      Image("https://www.example.com/xxx.png")// 直接加载网络地址,请填写一个具体的网络图片地址
        .alt($r('app.media.icon'))// 使用alt,在网络图片加载成功前使用占位图
        .width(100)
        .height(100)
    }
  }
}

为图片添加事件 

@Entry
@Component
struct ImageExample3 {
  @State widthValue: number = 0;
  @State heightValue: number = 0;
  private on: Resource = $r('app.media.image_on');
  private off: Resource = $r('app.media.image_off');
  private on2off: Resource = $r('app.media.image_on2off');
  private off2on: Resource = $r('app.media.image_off2on');
  @State src: Resource = this.on;

  build() {
    Column() {
      Row({ space: 20 }) {
        Column() {
          Image($r('app.media.img_example1'))
            .alt($r('app.media.ic_public_picture'))
            .sourceSize({
              width: 900,
              height: 900
            })
            .objectFit(ImageFit.Cover)
            .height(180).width(180)
            // 图片加载完成后,获取图片尺寸。
            .onComplete((msg: { width: number,height: number }) => {
              this.widthValue = msg.width
              this.heightValue = msg.height
            })
            .onError(() => {
              console.log('load image fail')
            })
            .overlay('\nwidth: ' + String(this.widthValue) + ' height: ' + String(this.heightValue), {
              align: Alignment.Bottom,
              offset: { x: 0, y: 20 }
            })
        }
        // 为图片添加点击事件,点击完成后加载特定图片
        Image(this.src)
          .width(120).height(120)
          .onClick(() => {
            if (this.src == this.on || this.src == this.off2on) {
              this.src = this.on2off
            } else {
              this.src = this.off2on
            }
          })
          .onFinish(() => {
            if (this.src == this.off2on) {
              this.src = this.on
            } else {
              this.src = this.off
            }
          })
      }
    }.width('100%')
  }
}

                        

 

拓展:

ImageKnife

专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单。

简介

本项目基于开源库 Glide 进行OpenHarmony的自研版本:

  • 支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存。
  • 支持磁盘缓存,对于下载图片会保存一份至磁盘当中。
  • 支持进行图片变换: 支持图像像素源图片变换效果。
  • 支持用户配置参数使用:( 例如:配置是否开启一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。
  • 推荐使用ImageKnifeComponent组件配合ImageKnifeOption参数来实现功能。
  • 支持用户自定义配置实现能力参考ImageKnifeComponent组件中对于入参ImageKnifeOption的处理。

下载安装

ohpm install @ohos/imageknife

使用说明

1.依赖配置

在entry\src\main\ets\entryability\EntryAbility.ts中做如下配置初始化全局ImageKnife实例:

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import { ImageKnife } from '@ohos/imageknife'

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage) {
    windowStage.loadContent('pages/Index', (err, data) => {
    });
    // 初始化全局ImageKnife 
    ImageKnife.with(this.context);
  	// 后续访问ImageKnife请通过:ImageKnifeGlobal.getInstance().getImageKnife()方式
  }
}
2.加载普通图片

接下来我们来写个简单实例看看:

import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife'

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'
  @State option: ImageKnifeOption = {
    loadSrc: $r('app.media.icon')
  }

  build() {
      Row() {
        Column() {
          Text(this.message)
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
          ImageKnifeComponent({ imageKnifeOption: this.option })
            .width(300)
            .height(300)
        }.width('100%')
      }.height('100%')
  }
}

非常简单,仅需定义一个ImageKnifeOption数据对象,然后在你需要的UI位置,加入ImageKnifeComponent自定义组件就可以加载出一张图像了。

3.加载SVG图片

加载svg其实和普通流程没有区别,只要将 loadSrc: $r('app.media.jpgSample'), 改成一张 loadSrc: $r('app.media.svgSample'), svg类型图片即可。

4.加载GIF图片

加载GIF其实和普通流程也没有区别只要将 loadSrc: $r('app.media.jpgSample'), 改成一张 loadSrc: $r('app.media.gifSample'), GIF图片即可。

4.1加载GIF图片

更改ImageKnifeOption对象的autoPlay(可选autoPlay = true为开始播放,autoPlay = false为暂停播放)

5.自定义Key

因为通常改变标识符比较困难或者根本不可能,所以ImageKnife也提供了 签名 API 来混合(你可以控制的)额外数据到你的缓存键中。 签名(signature)适用于媒体内容,也适用于你可以自行维护的一些版本元数据。

将签名传入加载请求

imageKnifeOption = {
                loadSrc: 'https://aahyhy.oss-cn-beijing.aliyuncs.com/blue.jpg',
                signature: new ObjectKey(new Date().getTime().toString())
              }

详细样例请参考SignatureTestPage文件

代码示例

6.自定义请求头规格

设置全局header并且设置request的header时,当key不同时全局和request并行,当key相同时request的header覆盖全局的header

7.自定义网络栈加载图片

7.1 自定义网络栈加载单个图片,在imageKnifeNextOption中添加customGetImage标签,然后完善custom函数的逻辑即可,

ImageKnifeNextComponent({
  imageKnifeNextOption: {
      loadSrc: 'http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg',
      placeholderSrc: $r('app.media.icon_loading'),
      errorholderSrc: $r('app.media.icon_failed'),
      customGetImage: custom
 }
}).width(100).height(100)
// 自定义实现图片获取方法,如自定义网络下载

@Concurrent
async function custom(context: Context, src: string): Promise<ArrayBuffer | undefined> {
  let result: DataFetchResult = new DataFetchResult();
  result.data = arraybuffer; //此处替换成自己网络获取的ArrayBuffer的逻辑
  return result;
}
7.2 自定义网络栈加载全部图片
1.先执行ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new CustomDataFetchClient()); 替换网络栈
2.在CustomDataFetchClient这个类中也通过下面的逻辑替换成自己网络获取的ArrayBuffer的逻辑
  let result: DataFetchResult = new DataFetchResult();
  result.data = arraybuffer; //此处替换成自己网络获取的ArrayBuffer的逻辑
  return result;
7.3 取消自定义网络栈加载全部图片
如果用户执行了自定义网络加载全部图片,后面又不想自定义网络栈加载全部图片了,可以通过下面的方式恢复
ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new CustomDataFetchClient()); 

ImageKnife更高阶用法参考:

OpenHarmony-TPC/ImageKnife (gitee.com)

 

  • 31
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值