arkts-graphics-display.md 10.5 KB
Newer Older
Z
zengyawen 已提交
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 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
# 显示图片


开发者经常需要在应用中显示一些图片,例如:按钮中的logo、网络图片、本地图片等。在应用中显示图片需要使用Image组件实现,Image支持多种图片格式,包括png、jpg、bmp、svg和gif,具体用法请参考[Image](../reference/arkui-ts/ts-basic-components-image.md)组件。


Image通过调用接口来创建,接口调用形式如下:



```ts
Image(src: string | Resource | media.PixelMap)
```


该接口通过图片数据源获取图片,支持本地图片和网络图片的渲染展示。其中,src是图片的数据源,加载方式请参考[加载图片资源](#加载图片资源)


## 加载图片资源

Image支持加载存档图、多媒体像素图两种类型。


### 存档图类型数据源

存档图类型的数据源可以分为本地资源、网络资源、Resource资源、媒体库datashare资源和base64。

- 本地资源
  创建文件夹,将本地图片放入ets文件夹下的任意位置。

  Image组件引入本地图片路径,即可显示图片(根目录为ets文件夹)。

  ```ts
  Image('images/view.jpg')
  .width(200)
  ```

- 网络资源
  引入网络图片需申请权限ohos.permission.INTERNET,具体申请方式请参考[权限申请声明](../security/accesstoken-guidelines.md)。此时,Image组件的src参数为网络图片的链接。

  ```ts
  Image('https://www.example.com/example.JPG') // 实际使用时请替换为真实地址
  ```

- Resource资源
  使用资源格式可以跨包/跨模块引入图片,resources文件夹下的图片都可以通过$r资源接口读 取到并转换到Resource格式。

  **图1** resouces  

  ![image-resource](figures/image-resource.jpg)

  调用方式:

  ```
  Image($r('app.media.icon'))
  ```

  还可以将图片放在rawfile文件夹下。

  **图2** rawfile  

 ![image-rawfile](figures/image-rawfile.jpg)

  调用方式:

  ```
  Image($rawfile('snap'))
  ```

- 媒体库datashare
  支持datashare://路径前缀的字符串,用于访问通过媒体库提供的图片路径。

  1. 调用接口获取图库的照片url。

      ```ts
      import picker from '@ohos.file.picker';

      @Entry
      @Component
      struct Index {
        private imgDatas: string[] = [];
        // 获取照片url集
        async getAllImg() {
          let photoPicker = new picker.PhotoViewPicker();
          let result = new Array<string>();
          try {
            let PhotoSelectOptions = new picker.PhotoSelectOptions();
            PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
            PhotoSelectOptions.maxSelectNumber = 5;
            let photoPicker = new picker.PhotoViewPicker();
            photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {
              result = PhotoSelectResult.photoUris;
            }).catch((err) => {
              console.error(`PhotoViewPicker.select failed with. Code: ${err.code}, message: ${err.message}`);
            });
          } catch (err) {
            console.error(`PhotoViewPicker failed with. Code: ${err.code}, message: ${err.message}`);    }
          return result;
        }

        // aboutToAppear中调用上述函数,获取图库的所有图片url,存在imgDatas中
        async aboutToAppear() {
          this.imgDatas = await this.getAllImg();
        }
        // 使用imgDatas的url加载图片。
        build() {
          Grid() {
            ForEach(this.imgDatas, item => {
              GridItem() {
                Image(item)
                  .width(200)
              }
            }, item => JSON.stringify(item))
          }
        }
      }
      ```
  2. 从媒体库获取的url格式通常如下。

      ```ts
      Image('datashare:///media/5')
      .width(200)
      ```

- base64
H
HelloCrease 已提交
126

Z
zengyawen 已提交
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 153 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
  路径格式为data:image/[png|jpeg|bmp|webp];base64,[base64 data],其中[base64 data]为Base64字符串数据。

  Base64格式字符串可用于存储图片的像素数据,在网页上使用较为广泛。


### 多媒体像素图

PixelMap是图片解码后的像素图,具体用法请参考[图片开发指导](../media/image.md)。以下示例将加载的网络图片返回的数据解码成PixelMap格式,再显示在Image组件上,

1. 创建PixelMap状态变量。

   ```ts
   @State image: PixelMap = undefined;
   ```

2. 引用多媒体。
   请求网络图片请求,解码编码PixelMap。

   1. 引用网络权限与媒体库权限。

       ```ts
       import http from '@ohos.net.http';
       import ResponseCode from '@ohos.net.http';
       import image from '@ohos.multimedia.image';
       ```
   2. 填写网络图片地址。

       ```ts
       http.createHttp().request("https://www.example.com/xxx.png",
         (error, data) => {
           if (error){
             console.error(`http reqeust failed with. Code: ${error.code}, message: ${error.message}`);
           } else {
           }
         }
       )
       ```
   3. 将网络地址成功返回的数据,编码转码成pixelMap的图片格式。

       ```ts
       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
       })
       ```
   4. 显示图片。

       ```ts
       Button("获取网络图片")
         .onClick(() => {
           this.httpRequest()
         })
       Image(this.image).height(100).width(100)
       ```


## 显示矢量图

Image组件可显示矢量图(svg格式的图片),支持的svg标签为:svg、rect、circle、ellipse、path、line、polyline、polygon和animate。

svg格式的图片可以使用fillColor属性改变图片的绘制颜色。


```ts
Image($r('app.media.cloud')).width(50)
.fillColor(Color.Blue) 
```

  **图3** 原始图片  
H
HelloCrease 已提交
205

Z
zengyawen 已提交
206 207 208
![屏幕截图_20230223_141141](figures/屏幕截图_20230223_141141.png)

  **图4** 设置绘制颜色后的svg图片  
H
HelloCrease 已提交
209

Z
zengyawen 已提交
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
![屏幕截图_20230223_141404](figures/屏幕截图_20230223_141404.png)


## 添加属性

给Image组件设置属性可以使图片显示更灵活,达到一些自定义的效果。以下是几个常用属性的使用示例,完整属性信息详见[Image](../reference/arkui-ts/ts-basic-components-image.md)


### 设置图片缩放类型

通过objectFit属性使图片缩放到高度和宽度确定的框内。


```ts
@Entry
@Component
struct MyComponent {
  scroller: Scroller = new Scroller()

  build() {
    Scroll(this.scroller) {
      Row() {
        Image($r('app.media.img_2')).width(200).height(150)
          .border({ width: 1 })
          .objectFit(ImageFit.Contain).margin(15) // 保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内。
          .overlay('Contain', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        Image($r('app.media.ic_img_2')).width(200).height(150)
          .border({ width: 1 })
          .objectFit(ImageFit.Cover).margin(15)
          // 保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界。
          .overlay('Cover', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        Image($r('app.media.img_2')).width(200).height(150)
          .border({ width: 1 })
            // 自适应显示。
          .objectFit(ImageFit.Auto).margin(15)
          .overlay('Auto', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
      }
      Row() {
        Image($r('app.media.img_2')).width(200).height(150)
          .border({ width: 1 })
          .objectFit(ImageFit.Fill).margin(15)
          // 不保持宽高比进行放大缩小,使得图片充满显示边界。
          .overlay('Fill', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        Image($r('app.media.img_2')).width(200).height(150)
          .border({ width: 1 })
          // 保持宽高比显示,图片缩小或者保持不变。
          .objectFit(ImageFit.ScaleDown).margin(15)
          .overlay('ScaleDown', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
        Image($r('app.media.img_2')).width(200).height(150)
          .border({ width: 1 })
          // 保持原有尺寸显示。
          .objectFit(ImageFit.None).margin(15)
          .overlay('None', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
      }
    }
  }
}
```

![zh-cn_image_0000001511421240](figures/zh-cn_image_0000001511421240.png)


### 同步加载图片

一般情况下,图片加载流程会异步进行,以避免阻塞主线程,影响UI交互。但是特定情况下,图片刷新时会出现闪烁,这时可以使用syncLoad属性,使图片同步加载,从而避免出现闪烁。不建议图片加载较长时间时使用,会导致页面无法响应。


```ts
Image($r('app.media.icon'))
  .syncLoad(true)
```


## 事件调用

通过在Image组件上绑定onComplete事件,图片加载成功后可以获取图片的必要信息。如果图片加载失败,也可以通过绑定onError回调来获得结果。


```ts
@Entry
@Component
struct MyComponent {
  @State widthValue: number = 0
  @State heightValue: number = 0
  @State componentWidth: number = 0
  @State componentHeight: number = 0

  build() {
    Column() {
      Row() {
        Image($r('app.media.ic_img_2'))
          .width(200)
          .height(150)
          .margin(15)
          .onComplete((msg: {
            width: number,
            height: number,
            componentWidth: number,
            componentHeight: number
          }) => {
            this.widthValue = msg.width
            this.heightValue = msg.height
            this.componentWidth = msg.componentWidth
            this.componentHeight = msg.componentHeight
          })
            // 图片获取失败,打印结果
          .onError(() => {
            console.info('load image fail')
          })
          .overlay('\nwidth: ' + String(this.widthValue) + ', height: ' + String(this.heightValue) + '\ncomponentWidth: ' + String(this.componentWidth) + '\ncomponentHeight: ' + String(this.componentHeight), {
            align: Alignment.Bottom,
            offset: { x: 0, y: 60 }
          })
      }
    }
  }
}
```


![zh-cn_image_0000001511740460](figures/zh-cn_image_0000001511740460.png)