# 4.3:图片组件

Image 用来加载并显示图片的基础组件,它支持从内存、本地和网络加载图片,当从网络加载图片的时候,需要申请网络访问权限。

# 4.3.1:限制与约束

  • 当加载网络图片时需要申请 ohos.permission.INTERNET 权限。

# 4.3.2:Image定义介绍

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

    Image($r("app.media.test"))
      .width(180)
      .height(80)
    
    1
    2
    3
    4_3_1

# 4.3.3: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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  • alt:设置占位图,图片显示之前先显示占位图,比如在加载网络图片或者图片加载失败时的场景。

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

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

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

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

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

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

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

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

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

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

      Image($r("app.media.test"))
        .width(90)
        .height(90)
        .renderMode(ImageRenderMode.Original) // 原图渲染
      
      Image($r("app.media.test"))
        .width(90)
        .height(90)
        .renderMode(ImageRenderMode.Template) // 模板渲染
      
      1
      2
      3
      4
      5
      6
      7
      8
      9

      样例运行结果如下图所示:

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

    Image($r("app.media.test"))
      .width(90)
      .height(90)
    
    Image($r("app.media.test"))
      .width(90)
      .height(90)
      .sourceSize({width: 10, height: 10}) // 设置解码的宽高
    
    1
    2
    3
    4
    5
    6
    7
    8

    样例运行结果如下图所示:

    4_3_4

# 4.3.4: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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  • onComplete:图片成功加载时触发该回调,返回图片原始尺寸信息。
  • onError:图片加载出现异常时触发该回调。
  • onFinish:当加载的源文件为带动效的 svg 图片时,当 svg 动效播放完成时会触发这个回调,如果动效为无限循环动效,则不会触发这个回调。

# 4.3.5: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;
          })
        }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
  • 从网络加载

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

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

样例运行结果如下图所示:

4_3_1

# 4.3.6: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')
      },
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

# 4.3.7:ImageKnife

ImageKnife (opens new window) 是基于开源库 Glide (opens new window) 进行自研的 OpenHarmony 版本,致力于打造一款更高效、更轻便、更简单的图片加载缓存库。

# 4.3.7.1:ImageKnife的特点:

  • 支持内存缓存

    ImageKnife 使用了 LRUCache 算法,对图片数据进行内存缓存。

  • 支持硬盘缓存

    ImageKnife 支持对下载的图片保存到磁盘中。

  • 支持图片变换

    ImageKnife 支持用户对图片做各种变换操作,比如圆角图片等。

  • 支持参数配置

    ImageKnife 支持用户配置相关参数,比如是否开启内存缓存,磁盘缓存策略以及占位图等。

  • 支持自定义实现

    读者参考 ImageKnifeComponent 组件中对于入参 ImageKnifeOption 的处理。

# 4.3.7.2:ImageKnife的使用:

  • 安装ImageKnife

    ImageKnife 是一个独立的三方库,使用之前需要先下载安装,在 Dev Eco Studio 的 Terminal 终端下进入项目的 entry 目录,执行如下命令:

    npm config set @ohos:registry=https://repo.harmonyos.com/npm/
    npm install @ohos/imageknife --save
    
    1
    2

    命令执行完毕,会在 entrynode_module 目录下下载 ImageKnife 库,如下图所示:

    4_3_6_2_1
  • 配置ImageKnife

    首先对 ImageKnife 进行全局初始化,在 app.ets 中调用 ImageKnifewith() 方法进行初始化,代码如下所示:

    import { ImageKnife } from '@ohos/imageknife'
    
    export default {
      data: {
        imageKnife: {}                            // ImageKnife全局占位符
      },
      onCreate() {
        console.info('Application onCreate')
        this.data.imageKnife = ImageKnife.with(); // ImageKnife占位符全局初始化赋值
      },
      onDestroy() {
        console.info('Application onDestroy')
      },
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
  • 使用ImageKnife

    使用 ImageKnife 加载并显示图片有2种方式,分别是使用自定义组件 ImageKnifeComponent 和原生组件 Image ,他们的使用如下:

    • 使用ImageKnifeComponent组件

      import { ImageKnifeOption, ImageKnifeComponent } from '@ohos/imageknife'
      
      @Entry @Component struct LottieTest {
      
        // 配置imageOption
        @State imageOptions: ImageKnifeOption = {
          loadSrc: $r('app.media.test'),
          size: { width: 200, height: 120 },
          placeholderSrc: $r('app.media.icon_failed'),
          errorholderSrc: $r("app.media.icon_failed")
        }
      
        build() {
          Column({space: 10}) {
            ImageKnifeComponent({// 使用自定义的ImageKnifeComponent组件
              imageKnifeOption: $imageOptions
            })
          }
          .width('100%')
          .height('100%')
          .padding(10)
        }
      
        aboutToDisappear() {
        }
      }
      
      // 配置ImageKnife
      var ImageKnife;
      var defaultTemp = globalThis.exports.default;
      if(defaultTemp != undefined) {
        ImageKnife = defaultTemp.data.imageKnife;
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
    • 使用Image组件

      import { RequestOption } from '@ohos/imageknife'
      
      @Entry @Component struct LottieTest {
      
        @State pixelMap: PixelMap = null;
      
        build() {
          Column({space: 10}) {
            Image(this.pixelMap)
              .width(200)
              .height(120)
          }
          .width('100%')
          .height('100%')
          .padding(10)
        }
      
        aboutToAppear() {
          let requestOption = new RequestOption();
          requestOption.load($r('app.media.test'))
          .addListener((error, data) => {
            if(data && data.isPixelMap()) {
              this.pixelMap = (data.imageKnifeValue as PixelMap)
              return true;
            }
            return false;
          })
          ImageKnife.call(requestOption)
        }
      }
      
      var ImageKnife;
      var defaultTemp = globalThis.exports.default;
      if(defaultTemp != undefined) {
        ImageKnife = defaultTemp.data.imageKnife;
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
  • ImageKnife的变换操作

    RequestOption 提供了一系列图片变换相关方法可供开发者调用,比如 centerCrop() 、模糊处理 blur() 、圆形剪切 cropCircle() 等方法,读者可参考 ImageKnife (opens new window) 文档了解更多功能。

(adsbygoogle = window.adsbygoogle || []).push({});
请作者喝杯咖啡

津公网安备 12011402001367号

津ICP备2020008934号-2