ts-basic-components-image.md 16.1 KB
Newer Older
Z
zengyawen 已提交
1 2
# Image

3
图片组件,支持本地图片和网络图片的渲染展示。
Z
zengyawen 已提交
4

5 6
> **说明:**
> 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
Z
zengyawen 已提交
7 8


9
## 权限说明
Z
zengyawen 已提交
10

11
使用网络图片时,需要在config.json(FA模型)或者module.json5(Stage模型)对应的"abilities"中添加网络使用权限ohos.permission.INTERNET。
Z
zengyawen 已提交
12

13
```
14 15 16 17 18 19 20 21
"abilities": [
  {
    ...
    "permissions": ["ohos.permission.INTERNET"],
    ...
  }
] 
```
Z
zengyawen 已提交
22

Z
zengyawen 已提交
23 24

## 子组件
Z
zengyawen 已提交
25 26 27



Z
zengyawen 已提交
28 29 30

## 接口

K
kukixi 已提交
31
Image(src: string | PixelMap | Resource)
Z
zengyawen 已提交
32

33
通过图片数据源获取图片,用于后续渲染展示。
Z
zengyawen 已提交
34

35 36
**参数:** 

H
HelloCrease 已提交
37 38
| 参数名  | 参数类型                                     | 必填   | 默认值  | 参数描述                                     |
| ---- | ---------------------------------------- | ---- | ---- | ---------------------------------------- |
39
| src  | string\|&nbsp;[PixelMap](../apis/js-apis-image.md#pixelmap7)&nbsp;\|&nbsp;[Resource](../../ui/ts-types.md#resource类型) | 是    | -    | 图片的数据源,支持本地图片和网络图片。<br/>当使用相对路径引用图片资源时,例如`Image("common/test.jpg")`,不支持该Image组件被跨包/跨模块调用,建议使用`$r`方式来管理需全局使用的图片资源。<br/>\- 支持的图片格式包括png、jpg、bmp、svg和gif。<br/>\- 支持`Base64`字符串。格式`data:image/[png\|jpeg\|bmp\|webp];base64,[base64 data]`, 其中`[base64 data]``Base64`字符串数据。<br/>\- 支持`dataability://`路径前缀的字符串,用于访问通过data&nbsp;ability提供的图片路径。 |
Z
zengyawen 已提交
40 41 42

## 属性

43 44
除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性:

G
gmy 已提交
45 46 47
| 名称                  | 参数类型                                                | 默认值                   | 描述                                                         |
| --------------------- | ------------------------------------------------------- | ------------------------ | ------------------------------------------------------------ |
| alt                   | string \| [Resource](../../ui/ts-types.md#resource类型) | -                        | 加载时显示的占位图,支持本地图片和网络图片。                 |
K
kangchongtao 已提交
48
| objectFit             | [ImageFit](ts-appendix-enums.md#imagefit)                           | ImageFit.Cover           | 设置图片的缩放类型。                                         |
G
gmy 已提交
49 50 51
| objectRepeat          | [ImageRepeat](ts-appendix-enums.md#imagerepeat)         | NoRepeat                 | 设置图片的重复样式。<br/>> **说明:**<br/>>&nbsp;-&nbsp;svg类型图源不支持该属性。 |
| interpolation         | [ImageInterpolation](#imageinterpolation)               | ImageInterpolation.None  | 设置图片的插值效果,即减轻低清晰度图片在放大显示的时候出现的锯齿问题,仅针对图片放大插值。<br/>>&nbsp;**说明:**<br/>>&nbsp;-&nbsp;svg类型图源不支持该属性。<br/>>&nbsp;-&nbsp;PixelMap资源不支持该属性。 |
| renderMode            | [ImageRenderMode](#imagerendermode)                     | ImageRenderMode.Original | 设置图片渲染的模式。<br/>>&nbsp;**说明:**<br/>>&nbsp;-&nbsp;svg类型图源不支持该属性。 |
H
HelloCrease 已提交
52 53
| sourceSize            | {<br/>width:&nbsp;number,<br/>height:&nbsp;number<br/>} | -                        | 设置图片裁剪尺寸,将原始图片解码成pixelMap,指定尺寸的图片,单位为px。<br/>>&nbsp;**说明:**<br/>>&nbsp;PixelMap资源不支持该属性。 |
| syncLoad<sup>8+</sup> | boolean                                  | false                    | 设置是否同步加载图片,默认是异步加载。同步加载时阻塞UI线程,不会显示占位图。  |
K
kangchongtao 已提交
54
| copyOption<sup>9+</sup> | [CopyOptions](ts-appendix-enums.md#copyoptions9)  | CopyOptions.None | 设置图片是否可复制(SVG图片不支持复制)。 |
55
| colorFilter<sup>9+</sup> | [ColorFilter](../../ui/ts-types.md) | - | 给图像设置颜色滤镜效果。 |
56 57

### ImageInterpolation
Z
zengyawen 已提交
58

H
HelloCrease 已提交
59 60 61 62 63 64
| 名称     | 描述                        |
| ------ | ------------------------- |
| None   | 不使用插值图片数据。                |
| High   | 插值图片数据的使用率高,可能会影响图片渲染的速度。 |
| Medium | 插值图片数据的使用率中。              |
| Low    | 插值图片数据的使用率低。              |
65 66 67

### ImageRenderMode

H
HelloCrease 已提交
68 69 70
| 名称       | 描述                    |
| -------- | --------------------- |
| Original | 按照原图进行渲染,包括颜色。        |
71 72 73
| Template | 将图片渲染为模板图片,忽略图片的颜色信息。 |

## 事件
Z
zengyawen 已提交
74

75 76
除支持[通用事件](ts-universal-events-click.md)外,还支持以下事件:

H
HelloCrease 已提交
77 78 79
| 名称                                       | 功能描述                                     |
| ---------------------------------------- | ---------------------------------------- |
| onComplete(callback:&nbsp;(event?:&nbsp;{&nbsp;width:&nbsp;number,&nbsp;height:&nbsp;number,&nbsp;componentWidth:&nbsp;number,<br>&nbsp;componentHeight:&nbsp;number,&nbsp;loadingStatus:&nbsp;number&nbsp;})&nbsp;=&gt;&nbsp;void) | 图片成功加载时触发该回调,返回成功加载的图片尺寸。<br>- width:图片的宽,单位为像素。<br/>- height:图片的高,单位为像素。<br/>- componentWidth:组件的宽,单位为像素。<br/>- componentHeight:组件的高,单位为像素。<br/>- loadingStatus:图片加载成功的状态。<br/> |
80 81
| onError(callback:&nbsp;(event?:&nbsp;{&nbsp;componentWidth:&nbsp;number,&nbsp;componentHeight:&nbsp;number&nbsp;})&nbsp;=&gt;&nbsp;void) | 图片加载出现异常时触发该回调。<br>- componentWidth:组件的宽,单位为像素。<br/>- componentHeight:组件的高,单位为像素。<br/> |
| onFinish(callback:&nbsp;()&nbsp;=&gt;&nbsp;void) | 当加载的源文件为带动效的svg图片时,当svg动效播放完成时会触发这个回调,如果动效为无限循环动效,则不会触发这个回调。 |
Z
zengyawen 已提交
82 83

## 示例
Z
zengyawen 已提交
84

85 86
### 图片加载

87
加载显示不同类型的图片,并设置图片的缩放类型。
88 89

```ts
Z
zengyawen 已提交
90 91 92
@Entry
@Component
struct ImageExample1 {
Z
zengyawen 已提交
93
  private on: string = 'www.example.com' 
Z
zengyawen 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
  @State src: string = this.on

  build() {
    Column() {
      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
        Text('default').fontSize(16).fontColor(0xcccccc).height(30)
        Row({ space: 5 }) {
          Image($r('app.media.ic_png'))
            .width(110).height(110).border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .overlay('png', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
          Image($r('app.media.ic_gif'))
            .width(110).height(110).border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .overlay('gif', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
          Image($r('app.media.ic_svg'))
            .width(110).height(110).border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .overlay('svg', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        }
        Row({ space: 5 }) {
          Image($r('app.media.img_example'))
            .width(110).height(110).border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .overlay('jpg', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
          Image(this.src)
            .width(110).height(110).border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .overlay('network', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        }.margin({ top: 25, bottom: 10 })
      }

      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
        Text('objectFit').fontSize(16).fontColor(0xcccccc).height(30)
        Row({ space: 5 }) {
          Image($r('app.media.img_example'))
            .border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .objectFit(ImageFit.None).width(110).height(110)
            .overlay('None', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
          Image($r('app.media.img_example'))
            .border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .objectFit(ImageFit.Fill).width(110).height(110)
            .overlay('Fill', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
          Image($r('app.media.img_example'))
            .border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .objectFit(ImageFit.Cover).width(110).height(110)
            .overlay('Cover', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        }
        Row({ space: 5 }) {
          Image($r('app.media.img_example_w250'))
            .border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .objectFit(ImageFit.Contain).width(110).height(110)
            .overlay('Contain', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
          Image($r('app.media.img_example_w250'))
            .border({ width: 1 }).borderStyle(BorderStyle.Dashed)
            .objectFit(ImageFit.ScaleDown).width(110).height(110)
            .overlay('ScaleDown', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        }.margin({ top: 25 })
      }
    }.height(320).width(360).padding({ right: 10, top: 10 })
  }
}
```

Z
zengyawen 已提交
153
![zh-cn_image_0000001250492613](figures/zh-cn_image_0000001250492613.gif)
Z
zengyawen 已提交
154

155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218


### 网络图片

加载网络图片时,默认网络超时是5分钟,建议使用alt配置加载时的占位图。如果需要更灵活的网络配置,可以使用SDK中提供的[HTTP](../../connectivity/http-request.md)工具包发送网络请求,接着将返回的数据解码为Image组件中的`PixelMap`,图片开发可参考[图片处理](../../media/image.md)。代码如下。

```tsx
// @ts-nocheck
import http from '@ohos.net.http';
import ResponseCode from '@ohos.net.http';
import image from '@ohos.multimedia.image'


@Entry 
@Component 
struct Index {
    
  // 先创建一个PixelMap状态变量用于接收网络图片
  @State image: PixelMap = undefined

  build() {
    Column({space: 10}) {
      Button("获取网络图片")
        .onClick(() => {
          this.httpRequest();
        })
      Image(this.image).height(100).width(100)
    }
    .width('100%')
    .height('100%')
    .padding(10)
  }

  // 网络图片请求方法
  private httpRequest() {
    let httpRequest = http.createHttp();
	
    httpRequest.request(
      "https://www.example.com/xxx.png",   // 请填写一个具体的网络图片地址
      (error, data) => {
        if(error) {
          console.log("error code: " + error.code + ", msg: " + error.message)
        } else {
          let code = data.responseCode
          if(ResponseCode.ResponseCode.OK == code) {
            let imageSource = image.createImageSource(data.result)
            let options = {alphaType: 0,                     // 透明度
                           editable: false,                  // 是否可编辑
                           pixelFormat: 3,                   // 像素格式
                           scaleMode: 1,                     // 缩略值
                           size: {height: 100, width: 100}}  // 创建图片大小
            imageSource.createPixelMap(options).then((pixelMap) => {
              this.image = pixelMap
            })
          } else {
            console.log("response code: " + code);
          }
        }
      }
    )
  }
}
```

219
**说明**:网络图片加载的请求方式、超时、额外请求参数等配置可以参考HTTP工具包中关于[`request()`](../../reference/apis/js-apis-http.md)请求方法的细节。
220

221 222 223
### 设置属性

```ts
Z
zengyawen 已提交
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
@Entry
@Component
struct ImageExample2 {

  build() {
    Column({ space: 10 }) {
      Text('renderMode').fontSize(12).fontColor(0xcccccc).width('96%').height(30)
      Row({ space: 50 }) {
        Image($r('app.media.img_example'))
          .renderMode(ImageRenderMode.Original).width(100).height(100)
          .border({ width: 1 }).borderStyle(BorderStyle.Dashed)
          .overlay('Original', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        Image($r('app.media.img_example'))
          .renderMode(ImageRenderMode.Template).width(100).height(100)
          .border({ width: 1 }).borderStyle(BorderStyle.Dashed)
          .overlay('Template', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
      }
241
      
Z
zengyawen 已提交
242 243 244 245
      Text('alt').fontSize(12).fontColor(0xcccccc).width('96%').height(30)
      Image('')
        .alt($r('app.media.Image_none'))
        .width(100).height(100).border({ width: 1 }).borderStyle(BorderStyle.Dashed)
246
        
Z
zengyawen 已提交
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
      Text('sourceSize').fontSize(12).fontColor(0xcccccc).width('96%')
      Row({ space: 50 }) {
        Image($r('app.media.img_example'))
          .sourceSize({
            width: 150,
            height: 150
          })
          .objectFit(ImageFit.ScaleDown).width('25%').aspectRatio(1)
          .border({ width: 1 }).borderStyle(BorderStyle.Dashed)
          .overlay('w:150 h:150', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        Image($r('app.media.img_example'))
          .sourceSize({
            width: 200,
            height: 200
          })
          .objectFit(ImageFit.ScaleDown).width('25%').aspectRatio(1)
          .border({ width: 1 }).borderStyle(BorderStyle.Dashed)
          .overlay('w:200 h:200', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
      }
266
      
Z
zengyawen 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
      Text('objectRepeat').fontSize(12).fontColor(0xcccccc).width('96%').height(30)
      Row({ space: 5 }) {
        Image($r('app.media.ic_health_heart'))
          .width(120).height(125).border({ width: 1 }).borderStyle(BorderStyle.Dashed)
          .objectRepeat(ImageRepeat.XY).objectFit(ImageFit.ScaleDown)
          .overlay('ImageRepeat.XY', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        Image($r('app.media.ic_health_heart'))
          .width(110).height(125).border({ width: 1 }).borderStyle(BorderStyle.Dashed)
          .objectRepeat(ImageRepeat.Y).objectFit(ImageFit.ScaleDown)
          .overlay('ImageRepeat.Y', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        Image($r('app.media.ic_health_heart'))
          .width(110).height(125).border({ width: 1 }).borderStyle(BorderStyle.Dashed)
          .objectRepeat(ImageRepeat.X).objectFit(ImageFit.ScaleDown)
          .overlay('ImageRepeat.X', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
      }
    }.height(150).width('100%').padding({ right: 10 })
  }
}
```

Z
zengyawen 已提交
287
![zh-cn_image_0000001205812616](figures/zh-cn_image_0000001205812616.png)
Z
zengyawen 已提交
288

289 290 291
### 事件调用

```ts
Z
zengyawen 已提交
292 293 294
@Entry
@Component
struct ImageExample3 {
T
tianyu 已提交
295 296
  @State widthValue: number = 0
  @State heightValue: number = 0
297 298 299 300
  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')
Z
zengyawen 已提交
301 302 303 304 305 306 307 308 309 310 311 312 313 314
  @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)
315
            // 图片加载完成后,获取图片尺寸。
Z
zengyawen 已提交
316
            .onComplete((msg: { width: number,height: number }) => {
T
tianyu 已提交
317 318
              this.widthValue = msg.width
              this.heightValue = msg.height
Z
zengyawen 已提交
319 320 321 322 323 324 325 326 327
            })
            .onError(() => {
              console.log('load image fail')
            })
            .overlay('\nwidth: ' + String(this.width) + ' height: ' + String(this.height), {
              align: Alignment.Bottom,
              offset: { x: 0, y: 20 }
            })
        }
328
        // 为图片添加点击事件,点击完成后加载特定图片。
Z
zengyawen 已提交
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
        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%')
  }
}
```

Z
zengyawen 已提交
351
![zh-cn_image_0000001205972610](figures/zh-cn_image_0000001205972610.gif)