大家好,我是潘Sir,持续分享IT技术,帮你少走弯路。《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新AI+编程、企业级项目实战等原创内容、欢迎关注!
ArkUI提供了丰富的系统组件,用于制作鸿蒙原生应用APP的UI,本文主要讲解Image图片组件的使用。
一、Image图片组件
1.1 概述
Image
为图片组件,用于在应用中显示图片。
1.2 图片参数
Image 组件的参数类型为string | Resource | media.PixelMap
,下面对三种参数类型逐一进行介绍。
1.2.1 string类型
string
类型的参数用于通过路径的方式引用图片,包括本地图片和网络图片。
- 本地图片
scss
Image('images/demo.jpg')
注意 :使用这种方式引入本地图片,需要将图片置于ets
目录下,并且需要为Image
组件提供图片相对于ets
目录的路径。
- 网络图片
rust
Image('http://xxx/xxx.jpg')
**注意:**真机中运行的鸿蒙应用,访问网络图片需要配置网络访问权限,不过在预览器和模拟器中测试时不受限制。权限配置相关的内容在后续章节会系统介绍。
1.2.2 Resource类型
Resource
类型的参数用于引入 resources 目录下的图片。
resources 目录用于统一存放应用所需的各种资源,包括图片、音频、视频、文本等等。下面简要介绍 resources 目录的用法,首先需要了解 resources 的目录结构,如下

resources 目录下,用于存放资源的子目录有(element 、media 、profile )和rawfile。下面分别介绍:
(1)element、media、profile
(element 、media 、profile )可存在多种版本,用于适配不同的环境,例如语言环境(zh_CN 和en_US )、系统主题(dark 和light )、设备类型(phone 和 tablet ) 等等。我们可以为上述每种环境各自准备一套资源文件,每种环境对应 resources 下的一个目录,例如上述的 zh_CN 和 en_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指的是图片的像素位图,其通常是一个二维数组,数组中的每个元素对应着图片中的一个像素,其包含了该像素的颜色等信息。像素位图主要用于图片编辑的场景。

示例代码:
在pages目录下新建component目录,通过并把对应的代码放到对应的组件目录下。新建image目录,在该目录下创建ImageParamenter.ets和images目录。
素材准备:将img_phone.png拷贝到images目录,将img_harmony.png拷贝到resources/base/media目录下,将img_phone.png拷贝到rawfile目录下。
ImageParamenter.ets代码
typescript
@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()
方法进行设置。例如
scss
Image($r('app.media.img'))
.width(100)
.height(100)
两个方法可接收的参数类型均为string | number | Resource
,下面对三种参数类型逐一进行介绍。
(1)string类型
string
类型的参数可为百分比,例如'100%'
,或者为具体尺寸,例如'100px'
。
具体尺寸的单位,常用的有两个,分别是px
和vp
,下面逐个介绍
px(Pixel)
物理像素,以像素个数来定义图像尺寸。这种方式的弊端是,在不同像素密度的屏幕上,相同的像素个数对应的物理尺寸是不同的。这样一来就会导致我们的应用在不同设备上显示的尺寸可能不同。如下图所示

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

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

(2)number
类型
number
类型的参数,默认以vp
作为单位。
(3)Resource
类型
Resource
类型参数用于引用resources 下的element目录中定义的数值。
引用element 目录中的数值,同样需要使用$r()
函数。要了解具体语法,需要先熟悉element目录下的文件内容。
前文提到过,element 目录中可保存各种类型的数值,且每种类型的值分别定义在一个JSON文件中。文件中的内容为键值对(name-value
)的形式。具体内容如下
element/string.json
json
{
"string": [
{
"name": "module_desc",
"value": "模块描述"
},
{
"name": "greeting",
"value": "你好"
}
]
}
element/integer.json
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文件
typescript
@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 |
自适应显示 |
各选项的效果如下图所示

代码示例:
在pages/component/image目录下新增ImageObjectFit.ets文件
typescript
@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 图片插值
当原图分辨率较低并且需要放大显示时,图片会模糊并出现锯齿。如下图所示

这时可以使用interpolation()
方法对图片进行插值,使图片显示得更清晰。该方法的参数为ImageInterpolation
枚举类型,可选的值有
名称 | 描述 |
---|---|
ImageInterpolation.None |
不使用图片插值。 |
ImageInterpolation.High |
高质量插值,可能会影响图片渲染的速度。 |
ImageInterpolation.Medium |
中等质量插值。 |
ImageInterpolation.Low |
低等质量插值。 |
各选项效果如下图所示

代码示例:
将img_flower.png 拷贝到resources/base/media目录下
在pages/component/image目录下新增ImageInterpolationPage.ets文件
typescript
@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下添加:
json
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
具体参见官网说明
developer.huawei.com/consumer/cn...
附录:屏幕参数
想要理解px和vp尺寸单位,需要大家先掌握屏幕相关的几个参数
- 像素
屏幕显示的最小单位,屏幕上的一个小亮点称为一个像素。
- 分辨率
屏幕上横向和纵向的像素数量。
- 尺寸
屏幕对角线的长度,以英寸(inches
)为单位。
- 像素密度
像素密度是每英寸屏幕上的像素数量,通常以PPI
(Pixels Per Inch)表示,计算公式如下。较高的像素密度意味着在相同尺寸的屏幕上有更多的像素,从而提供更加清晰和细腻的图像。

如下图所示

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