鸿蒙应用开发从入门到实战(十):ArkUI图片组件Image

简介: ArkUI提供了丰富的系统组件,用于制作鸿蒙原生应用APP的UI,本文主要讲解Image图片组件的使用。

大家好,我是潘Sir,持续分享IT技术,帮你少走弯路。《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新AI+编程、企业级项目实战等原创内容、欢迎关注!

ArkUI提供了丰富的系统组件,用于制作鸿蒙原生应用APP的UI,本文主要讲解Image图片组件的使用。

一、Image图片组件

1.1 概述

Image为图片组件,用于在应用中显示图片。

1.2 图片参数

Image组件的参数类型为string | Resource | media.PixelMap,下面对三种参数类型逐一进行介绍。

1.2.1 string类型

string类型的参数用于通过路径的方式引用图片,包括本地图片和网络图片。

  • 本地图片
Image('images/demo.jpg')

注意:使用这种方式引入本地图片,需要将图片置于ets目录下,并且需要为Image组件提供图片相对于ets目录的路径。

  • 网络图片
Image('http://xxx/xxx.jpg')

注意:真机中运行的鸿蒙应用,访问网络图片需要配置网络访问权限,不过在预览器和模拟器中测试时不受限制。权限配置相关的内容在后续章节会系统介绍。

1.2.2 Resource类型

Resource类型的参数用于引入 resources 目录下的图片。

resources目录用于统一存放应用所需的各种资源,包括图片、音频、视频、文本等等。下面简要介绍 resources 目录的用法,首先需要了解 resources 的目录结构,如下

1resources目录结构.png

resources 目录下,用于存放资源的子目录有(elementmediaprofile)和rawfile。下面分别介绍:

(1)element、media、profile

elementmediaprofile)可存在多种版本,用于适配不同的环境,例如语言环境(zh_CNen_US)、系统主题(darklight)、设备类型(phonetablet) 等等。我们可以为上述每种环境各自准备一套资源文件,每种环境对应 resources 下的一个目录,例如上述的 zh_CNen_US。我们在使用resources下的资源时,无需指定具体的环境版本,系统会根据设备所处的环境自动选择匹配的版本,例如当设备系统语言为中文时,则会使用zh_CN目录下的资源,为英文时,则会使用en_US目录下的资源。若没有与当前所处环境相对应的版本,则使用 base 目录下资源

各目录存储的具体资源如下

  • media

存放媒体资源,包括图片、音频、视频等文件。

  • element

存放用于描述页面元素的尺寸、颜色、样式等的各种类型的值,每种类型的值都定义在一个相应的 JSON 文件中。

  • profile

存放自定义配置文件。

(2)rawfile

​ 用于存储任意格式的原始文件,需要注意的是rawfile不会根据设备所处的环境去匹配不同的资源。

总结:

resources目录下可用于存放图片的目录有resources/*/media 以及 resources/rawfile,两个目录下图片的使用方式有所不同,下面逐一介绍

  • media目录

    该目录下的资源,需要使用$r('app.media.<filename>')的方式引用。

    注意:无需指定具体版本,系统会自动根据所处环境选择相应版本

    例如上图中的img.png图片,可通过$r('app.media.img')引用。需要注意的是$r()的返回值即为 Resource 类型,因此可以直接将$r('app.media.img')作为 Image 组件的参数,例如Image($r('app.media.img'))

  • rawfile目录

    该目录下的资源,可通过$rawfile('path/to/your/file')的方式引用,文件的路径为相对于 rawfile 的路径。例如上图中的icon.png,须使用$rawfile('icon.png)引用。需要注意的是,$rawfile()的返回值也是Resource类型,因此其也可以直接作为 Image 组件的参数,如Image($rawfile('icon.png))

1.2.3 media.PixelMap

PixelMap指的是图片的像素位图,其通常是一个二维数组,数组中的每个元素对应着图片中的一个像素,其包含了该像素的颜色等信息。像素位图主要用于图片编辑的场景。

10像素位图.png

示例代码:

​ 在pages目录下新建component目录,通过并把对应的代码放到对应的组件目录下。新建image目录,在该目录下创建ImageParamenter.ets和images目录。

​ 素材准备:将img_phone.png拷贝到images目录,将img_harmony.png拷贝到resources/base/media目录下,将img_phone.png拷贝到rawfile目录下。

​ ImageParamenter.ets代码

@Entry
@Component
// 图片参数
struct ImageParamenter {
   

  build() {
   
    Column({
    space: 40 }) {
   
      // 1、string类型
      //本地图片,位于ets目录
      Image('pages/component/image/images/img_phone.png')
        .width(150)
        .height(150)

      //网络图片
      Image('https://developer.harmonyos.com/resource/image/new/home/img_DLP_jiazhi_2.png')
        .width(150)
        .height(150)

      // 2、Resource类型
      //本地图片,位于resource/*/media目录
      Image($r('app.media.img_harmony'))
        .width(150)
        .height(150)

      //本地图片,位于resource/rawfile目录
      Image($rawfile('img_phone.png'))
        .width(150)
        .height(150)

    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

1.3 常用属性

1.3.1 图片尺寸

图片尺寸可通过width()方法和height()方法进行设置。例如

Image($r('app.media.img'))
    .width(100)
    .height(100)

两个方法可接收的参数类型均为string | number | Resource,下面对三种参数类型逐一进行介绍。

(1)string类型

string类型的参数可为百分比,例如'100%',或者为具体尺寸,例如'100px'

具体尺寸的单位,常用的有两个,分别是pxvp,下面逐个介绍

  • px(Pixel)

物理像素,以像素个数来定义图像尺寸。这种方式的弊端是,在不同像素密度的屏幕上,相同的像素个数对应的物理尺寸是不同的。这样一来就会导致我们的应用在不同设备上显示的尺寸可能不同。如下图所示

2物理像素.png

  • vp(Virtual Pixel)

为了保证一致的观感,我们可以使用虚拟像素作为单位。虚拟像素是一种可根据屏幕像素密度灵活缩放的单位。1vp相当于像素密度为160ppi的屏幕上的1px。在不同像素密度的屏幕上,HarmonyOS会根据如下公式将虚拟像素换算为对应的物理像素

3vp公式.png

根据上述公式,不难看出,使用虚拟像素作为单位时,同一尺寸,在像素密度低的屏幕上(单个像素的物理尺寸大),对应的物理像素会更少,相反在像素密度高的屏幕上(单个像素的物理尺寸小),对应的物理像素会更多。因此就能在不同像素密度的屏幕上,获得基本一致的观感了。如下图所示

4虚拟像素.png

(2)number类型

number类型的参数,默认以vp作为单位。

(3)Resource类型

Resource类型参数用于引用resources下的element目录中定义的数值。

引用element目录中的数值,同样需要使用$r()函数。要了解具体语法,需要先熟悉element目录下的文件内容。

前文提到过,element目录中可保存各种类型的数值,且每种类型的值分别定义在一个JSON文件中。文件中的内容为键值对(name-value)的形式。具体内容如下

element/string.json

{
  "string": [
    {
      "name": "module_desc",
      "value": "模块描述"
    },
    {
      "name": "greeting",
      "value": "你好"
    }
  ]
}

element/integer.json

{
  "integer": [
    {
      "name": "width",
      "value": 150
    },
    {
      "name": "height",
      "value": 150
    }
  ]
}

我们可以通过 name 引用相应的 value。具体语法为$r('app..')

注意:无需指定具体版本,系统会自动根据所处环境选择相应版本

例如上述的 greeting 的值,可通过$r('app.string.greeting')引用,width的值可通过$r('app.integer.width')

示例代码:

在resources/base/element目录下新增integer.json文件

在pages/component/image目录下新增ImageSizePage.ets文件

@Entry
@Component
  // 图片尺寸
struct ImageSizePage {
   
  @State message: string = 'Hello World'

  build() {
   
    Column({
    space: 20 }) {
   

      // 1、属性方法参数为string类型
      //1.1 单位为px
      Row({
    space: 20 }) {
   
        Column() {
   
          Image($r('app.media.img_harmony'))
            .width('450px')
            .height('450px')
          Text('宽高:450px')
        }

        //1.2 单位为vp
        Column() {
   
          Image($r('app.media.img_harmony'))
            .width('150vp')
            .height('150vp')
          Text('宽高:150vp')
        }
      }

      // 2、属性方法参数为number类型,默认单位为vp
      Row({
    space: 20 }) {
   
        Column() {
   
          Image($r('app.media.img_harmony'))
            .width(150)
            .height(150)
          Text('宽高:150')
        }

        // 3、属性方法参数为Resource类型,读取integer.json文件
        Column() {
   
          Image($r('app.media.img_harmony'))
            .width($r('app.integer.width'))
            .height($r('app.integer.height'))
          Text('宽高:150')
        }
      }

    }.width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

1.3.2 图片缩放

当图片的原始大小与Image组件不同时,可通过objectFit()方法来设置图片的显示效果。该方法的参数类型为ImageFit枚举类型,可选的枚举值如下

名称 描述
ImageFit.None 保持原有尺寸显示,不做任何缩放,超出显示区域的部分不显示。
ImageFit.Contain 保持宽高比进行缩小或者放大,使得显示区域刚好包含整个图片。
ImageFit.Cover 保持宽高比进行缩小或者放大,使得图片刚好完全覆盖显示区域。
ImageFit.Fill 不保持宽高比进行放大缩小,使得图片充满显示区域。
ImageFit.ScaleDown 保持宽高比进行缩小或不变(不会放大),使得图片完全显示在显示区域内。
ImageFit.Auto 自适应显示

各选项的效果如下图所示

7缩放效果.png

代码示例:

在pages/component/image目录下新增ImageObjectFit.ets文件

@Entry
@Component
// 图片缩放
struct ImageObjectFit {
   

  build() {
   
    Column({
    space: 20 }) {
   

      Column() {
   
        Image($r('app.media.img_harmony'))
          .width('720px')
          .height('334px')
        Text('原图')
      }

      Row({
    space: 20 }) {
   
        Column() {
   
          Image($r('app.media.img_harmony'))
            .width('450px')
            .height('450px')
            .borderWidth(1)
            .objectFit(ImageFit.None)
          Text('None')
        }

        Column() {
   
          Image($r('app.media.img_harmony'))
            .width('450px')
            .height('450px')
            .borderWidth(1)
            .objectFit(ImageFit.Contain)
          Text('Contain')
        }
      }

      Row({
    space: 20 }) {
   
        Column() {
   
          Image($r('app.media.img_harmony'))
            .width('450px')
            .height('450px')
            .borderWidth(1)
            .objectFit(ImageFit.Cover)
          Text('Cover')
        }

        Column() {
   
          Image($r('app.media.img_harmony'))
            .width('450px')
            .height('450px')
            .borderWidth(1)
            .objectFit(ImageFit.Fill)
          Text('Fill')
        }
      }

      Row({
    space: 20 }) {
   
        Column() {
   
          Image($r('app.media.img_harmony'))
            .width('450px')
            .height('450px')
            .borderWidth(1)
            .objectFit(ImageFit.ScaleDown)
          Text('ScaleDown')
        }

        Column() {
   
          Image($r('app.media.img_harmony'))
            .width('450px')
            .height('450px')
            .borderWidth(1)
            .objectFit(ImageFit.Auto)
          Text('Auto')
        }
      }
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')
  }
}

1.3.3 图片插值

当原图分辨率较低并且需要放大显示时,图片会模糊并出现锯齿。如下图所示

8图片插值.png

这时可以使用interpolation()方法对图片进行插值,使图片显示得更清晰。该方法的参数为ImageInterpolation枚举类型,可选的值有

名称 描述
ImageInterpolation.None 不使用图片插值。
ImageInterpolation.High 高质量插值,可能会影响图片渲染的速度。
ImageInterpolation.Medium 中等质量插值。
ImageInterpolation.Low 低等质量插值。

各选项效果如下图所示

9图片插值效果.png

代码示例:

将img_flower.png 拷贝到resources/base/media目录下

在pages/component/image目录下新增ImageInterpolationPage.ets文件

@Entry
@Component
// 图片插值
struct ImageInterpolationPage {
   

  build() {
   
    Column({
    space: 50 }) {
   
      Row({
    space: 20 }) {
   
        Column() {
   
          Image($r('app.media.img_flower'))
            .width('500px')
            .height('500px')
            .interpolation(ImageInterpolation.None)
          Text('None')
        }

        Column() {
   
          Image($r('app.media.img_flower'))
            .width('500px')
            .height('500px')
            .interpolation(ImageInterpolation.Low)
          Text('Low')
        }
      }


      Row({
    space: 20 }) {
   
        Column() {
   
          Image($r('app.media.img_flower'))
            .width('500px')
            .height('500px')
            .interpolation(ImageInterpolation.Medium)
          Text('Medium')

        }

        Column() {
   
          Image($r('app.media.img_flower'))
            .width('500px')
            .height('500px')
            .interpolation(ImageInterpolation.High)
          Text('High')
        }
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

二、权限申请

真机或模拟器查看网络图片,需要申请网络访问权限:ohos.permission.INTERNET

为了方便测试,在EntryAbility.ts文件中修改启动页为:pages/component/image/ImageParamenter

页面路径可以在resources/base/profile/main_pages.json文件中查看

在module.json5文件的module下添加:

"requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ],

具体参见官网说明

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/accesstoken-guidelines-0000001493744016-V2

附录:屏幕参数

想要理解px和vp尺寸单位,需要大家先掌握屏幕相关的几个参数

  • 像素

屏幕显示的最小单位,屏幕上的一个小亮点称为一个像素。

  • 分辨率

屏幕上横向和纵向的像素数量。

  • 尺寸

屏幕对角线的长度,以英寸(inches)为单位。

  • 像素密度

像素密度是每英寸屏幕上的像素数量,通常以PPI(Pixels Per Inch)表示,计算公式如下。较高的像素密度意味着在相同尺寸的屏幕上有更多的像素,从而提供更加清晰和细腻的图像。
5像素密度.png

如下图所示

6屏幕参数.png

《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新AI+编程、企业级项目实战等原创内容,防止迷路,欢迎关注!

相关文章
|
4天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1104 0
|
3天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
500 10
|
13天前
|
人工智能 运维 安全
|
12天前
|
人工智能 测试技术 API
智能体(AI Agent)搭建全攻略:从概念到实践的终极指南
在人工智能浪潮中,智能体(AI Agent)正成为变革性技术。它们具备自主决策、环境感知、任务执行等能力,广泛应用于日常任务与商业流程。本文详解智能体概念、架构及七步搭建指南,助你打造专属智能体,迎接智能自动化新时代。
|
4天前
|
弹性计算 Kubernetes jenkins
如何在 ECS/EKS 集群中有效使用 Jenkins
本文探讨了如何将 Jenkins 与 AWS ECS 和 EKS 集群集成,以构建高效、灵活且具备自动扩缩容能力的 CI/CD 流水线,提升软件交付效率并优化资源成本。
300 0
|
11天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
|
12天前
|
机器学习/深度学习 人工智能 自然语言处理
B站开源IndexTTS2,用极致表现力颠覆听觉体验
在语音合成技术不断演进的背景下,早期版本的IndexTTS虽然在多场景应用中展现出良好的表现,但在情感表达的细腻度与时长控制的精准性方面仍存在提升空间。为了解决这些问题,并进一步推动零样本语音合成在实际场景中的落地能力,B站语音团队对模型架构与训练策略进行了深度优化,推出了全新一代语音合成模型——IndexTTS2 。
802 23
|
4天前
|
缓存 供应链 监控
VVIC seller_search 排行榜搜索接口深度分析及 Python 实现
VVIC搜款网seller_search接口提供服装批发市场的商品及商家排行榜数据,涵盖热销榜、销量排名、类目趋势等,支持多维度筛选与数据分析,助力选品决策、竞品分析与市场预测,为服装供应链提供有力数据支撑。
|
4天前
|
缓存 监控 API
Amazon item_review 商品评论接口深度分析及 Python 实现
亚马逊商品评论接口(item_review)可获取用户评分、评论内容及时间等数据,支持多维度筛选与分页调用,结合Python实现情感分析、关键词提取与可视化,助力竞品分析、产品优化与市场决策。