• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Displaying Images (Image)
2
3
4More often than not, you may need to display images in your application, for example, logos in buttons, online images, and local images. This is where the **\<Image>** component comes in handy. The **\<Image>** component supports a wide range of image formats, including PNG, JPG, BMP, SVG, and GIF. For details, see [Image](../reference/arkui-ts/ts-basic-components-image.md).
5
6
7To use the **\<Image>** component, call the following API:
8
9
10
11```ts
12Image(src: PixelMap | ResourceStr | DrawableDescriptor)
13```
14
15
16This API obtains a local or online image from the data source specified by **src**. For details about how to load the data source, see [Loading Image Resources](#loading-image-resources).
17
18
19## Loading Image Resources
20
21The **\<Image>** component supports two types of images: archived and pixel map.
22
23
24### Archived Type Data Sources
25
26Data sources of the archived type can be classified into local resources, online resources, **Resource** objects, media library resources, and Base64 resources.
27
28- Local resources
29
30  To load local images, create an **ets** folder and place the local images in any position in the folder.
31
32  Then, in the **\<Image>** component, set **src** to the local image path, with the root directory being the **ets** folder.
33
34  ```ts
35  Image('images/view.jpg')
36  .width(200)
37  ```
38
39- Online resources
40
41  To use online images, first apply for the **ohos.permission.INTERNET** permission. For details, see [Applying for Permissions](../security/accesstoken-guidelines.md). Then, in the **\<Image>** component, set **src** to the URL of the online image.
42
43  ```ts
44  Image('https://www.example.com/example.JPG') // Replace the URL with the actual URL.
45  ```
46
47- **Resource** objects
48
49  **Resource** objects can be used to import images across bundles and modules.
50
51  To load **Resource** objects, place images in the **resources** folder, which can be read and converted to the **Resource** objects through **$r**.
52
53  **Figure 1** resources folder
54
55  ![image-resource](figures/image-resource.jpg)
56
57  API:
58
59  ```
60  Image($r('app.media.icon'))
61  ```
62
63  You can also place the images in the **rawfile** folder.
64
65  **Figure 2** rawfile folder
66
67  ![image-rawfile](figures/image-rawfile.jpg)
68
69  API:
70
71  ```
72  Image($rawfile('example1'))
73  ```
74
75- Media library **file://data/storage**
76
77  To load images from the media library, use a path string that starts with **file://**.
78
79  1. Call the API to obtain the image URL in the media library.
80      ```ts
81      import picker from '@ohos.file.picker';
82      import { BusinessError } from '@ohos.base';
83
84      @Entry
85      @Component
86      struct Index {
87        @State imgDatas: string[] = [];
88        // Obtain the image URL set.
89        getAllImg() {
90          let result = new Array<string>();
91          try {
92            let PhotoSelectOptions:picker.PhotoSelectOptions = new picker.PhotoSelectOptions();
93            PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
94            PhotoSelectOptions.maxSelectNumber = 5;
95            let photoPicker:picker.PhotoViewPicker = new picker.PhotoViewPicker();
96            photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult:picker.PhotoSelectResult) => {
97              this.imgDatas = PhotoSelectResult.photoUris;
98              console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(PhotoSelectResult));
99            }).catch((err:Error) => {
100              let message = (err as BusinessError).message;
101              let code = (err as BusinessError).code;
102              console.error(`PhotoViewPicker.select failed with. Code: ${code}, message: ${message}`);
103            });
104          } catch (err) {
105            let message = (err as BusinessError).message;
106            let code = (err as BusinessError).code;
107            console.error(`PhotoViewPicker failed with. Code: ${code}, message: ${message}`);    }
108        }
109
110        // Call the preceding function in aboutToAppear to obtain the image URL set and store the URLs in imgDatas.
111        async aboutToAppear() {
112          this.getAllImg();
113        }
114        // Use the URL of imgDatas to load the image.
115        build() {
116          Column() {
117            Grid() {
118              ForEach(this.imgDatas, (item:string) => {
119                GridItem() {
120                  Image(item)
121                    .width(200)
122                }
123              }, (item:string):string => JSON.stringify(item))
124            }
125          }.width('100%').height('100%')
126        }
127      }
128      ```
129
130  2. Check the format of the URL obtained from the media library:
131      ```ts
132      Image('file://media/Photos/5')
133      .width(200)
134      ```
135
136- Base64
137
138  As shown above, the URL format is data:image/[png|jpeg|bmp|webp];base64,[base64 data], where **[base64 data]** indicates a Base64 string.
139
140  Base64 strings are widely used on web pages for storing pixel data of images.
141
142
143### Pixel Map
144
145A pixel map is a pixel image obtained after image decoding. For details, see [Image Development](../media/image-overview.md). In the following example, the data returned by the loaded online image is decoded into a pixel map, which is then displayed on the **\<Image>** component.
146
1471. Create a **PixelMap** state variable.
148
149   ```ts
150   @State image: PixelMap = undefined;
151   ```
152
1532. Reference multimedia.
154
155   Request an online image and implement transcoding to generate a pixel map.
156
157   1. Reference the network and media library access permissions.
158       ```ts
159       import http from '@ohos.net.http';
160       import ResponseCode from '@ohos.net.http';
161       import image from '@ohos.multimedia.image';
162       ```
163   2. Enter the online image address.
164       ```ts
165       http.createHttp().request("https://www.example.com/xxx.png",
166         (error:Error) => {
167           if (error){
168             console.error(`http reqeust failed with. Code: ${error.code}, message: ${error.message}`);
169           } else {
170           }
171         }
172       )
173       ```
174   3. Transcode the data returned by the online image address to a pixel map.
175       ```ts
176       let code:object = data.responseCode;
177       if (ResponseCode.ResponseCode.OK === code) {
178         let imageSource:image = image.createImageSource(data.result);
179         class tmp{
180           height:number = 100
181           width:number = 100
182         }
183         let si:tmp = new tmp()
184         let options:Record<string,number|boolean|tmp> = {
185           'alphaType': 0, // Alpha type.
186           'editable': false, // Whether the image is editable.
187           'pixelFormat': 3, // Pixel format.
188           'scaleMode': 1, // Scale mode.
189           'size': { height: 100, width: 100 }
190         }  // Image size.
191         class imagetmp{
192           image:image
193           set(val:PixelMap){
194             this.image = val
195           }
196         }
197          imageSource.createPixelMap(options).then((pixelMap:PixelMap) => {
198          let im = new imagetmp()
199            im.set(pixelMap)
200       })
201       }
202       ```
203   4. Display the image.
204       ```ts
205       class htp{
206        httpRequest:Function|undefined = undefined
207        set(){
208          if(this.httpRequest){
209          this.httpRequest()
210          }
211        }
212      }
213       Button ("Get Online Image")
214         .onClick(() => {
215           let sethtp = new htp()
216           sethtp.set()
217         })
218       Image(this.image).height(100).width(100)
219       ```
220
221
222## Displaying Vector Images
223
224The **\<Image>** component can display vector images in SVG format. The supported SVG labels are **svg**, **rect**, **circle**, **ellipse**, **path**, **line**, **polyline**, **polygon**, and **animate**.
225
226You can use the **fillColor** attribute to change the fill color of an SVG image.
227
228
229```ts
230Image($r('app.media.cloud')).width(50)
231.fillColor(Color.Blue)
232```
233
234  **Figure 3** Original image
235
236![screenshot_20230223_141141](figures/screenshot_20230223_141141.png)
237
238  **Figure 4** SVG image after the fill color is set
239
240![screenshot_20230223_141404](figures/screenshot_20230223_141404.png)
241
242
243## Setting Attributes
244
245Setting attributes for the **\<Image>** component can spruce up the image with custom effects. The following are usage examples of common attributes. For details about all attributes, see [Image](../reference/arkui-ts/ts-basic-components-image.md).
246
247
248### Setting the Image Scale Mode
249
250You can use the **objectFit** attribute to scale an image to fit it into a container whose height and width are determined.
251
252
253```ts
254@Entry
255@Component
256struct MyComponent {
257  scroller: Scroller = new Scroller()
258
259  build() {
260    Scroll(this.scroller) {
261      Row() {
262        Image($r('app.media.img_2')).width(200).height(150)
263          .border({ width: 1 })
264          .objectFit(ImageFit.Contain).margin(15) // The image is scaled with its aspect ratio retained to fit within the display boundaries.
265          .overlay('Contain', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
266        Image($r('app.media.ic_img_2')).width(200).height(150)
267          .border({ width: 1 })
268          .objectFit(ImageFit.Cover).margin(15)
269          // The image is scaled with its aspect ratio retained for both sides to be greater than or equal to the display boundaries.
270          .overlay('Cover', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
271        Image($r('app.media.img_2')).width(200).height(150)
272          .border({ width: 1 })
273            // The image is scaled automatically to fit the display area.
274          .objectFit(ImageFit.Auto).margin(15)
275          .overlay('Auto', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
276      }
277      Row() {
278        Image($r('app.media.img_2')).width(200).height(150)
279          .border({ width: 1 })
280          .objectFit(ImageFit.Fill).margin(15)
281          // The image is scaled to fill the display area, and its aspect ratio is not retained.
282          .overlay('Fill', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
283        Image($r('app.media.img_2')).width(200).height(150)
284          .border({ width: 1 })
285          // The image content is displayed with its aspect ratio retained. The size is smaller than or equal to the original size.
286          .objectFit(ImageFit.ScaleDown).margin(15)
287          .overlay('ScaleDown', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
288        Image($r('app.media.img_2')).width(200).height(150)
289          .border({ width: 1 })
290          // The original size is retained.
291          .objectFit(ImageFit.None).margin(15)
292          .overlay('None', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
293      }
294    }
295  }
296}
297```
298
299![en-us_image_0000001622804833](figures/en-us_image_0000001622804833.png)
300
301
302### Using Image Interpolation
303
304An image of low resolution may suffer quality loss with aliasing when scaled up. If this is the case, you can use the **interpolation** attribute to conduct image interpolation and improve image quality.
305
306
307```ts
308@Entry
309@Component
310struct Index {
311  build() {
312    Column() {
313      Row() {
314        Image($r('app.media.grass'))
315          .width('40%')
316          .interpolation(ImageInterpolation.None)
317          .borderWidth(1)
318          .overlay("Interpolation.None", { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
319          .margin(10)
320        Image($r('app.media.grass'))
321          .width('40%')
322          .interpolation(ImageInterpolation.Low)
323          .borderWidth(1)
324          .overlay("Interpolation.Low", { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
325          .margin(10)
326      }.width('100%')
327      .justifyContent(FlexAlign.Center)
328
329      Row() {
330        Image($r('app.media.grass'))
331          .width('40%')
332          .interpolation(ImageInterpolation.Medium)
333          .borderWidth(1)
334          .overlay("Interpolation.Medium", { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
335          .margin(10)
336        Image($r('app.media.grass'))
337          .width('40%')
338          .interpolation(ImageInterpolation.High)
339          .borderWidth(1)
340          .overlay("Interpolation.High", { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
341          .margin(10)
342      }.width('100%')
343      .justifyContent(FlexAlign.Center)
344    }
345    .height('100%')
346  }
347}
348```
349
350![en-us_image_0000001643127365](figures/en-us_image_0000001643127365.png)
351
352
353### Setting Image Repeat Pattern
354
355You can use the **objectRepeat** attribute to set the repeat pattern of an image. For details, see [ImageRepeat](../reference/arkui-ts/ts-appendix-enums.md#imagerepeat).
356
357
358```ts
359@Entry
360@Component
361struct MyComponent {
362  build() {
363    Column({ space: 10 }) {
364      Row({ space: 5 }) {
365        Image($r('app.media.ic_public_favor_filled_1'))
366          .width(110)
367          .height(115)
368          .border({ width: 1 })
369          .objectRepeat(ImageRepeat.XY)
370          .objectFit(ImageFit.ScaleDown)
371          // Repeat the image along both the horizontal and vertical axes.
372          .overlay('ImageRepeat.XY', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
373        Image($r('app.media.ic_public_favor_filled_1'))
374          .width(110)
375          .height(115)
376          .border({ width: 1 })
377          .objectRepeat(ImageRepeat.Y)
378          .objectFit(ImageFit.ScaleDown)
379          // Repeat the image only along the vertical axis.
380          .overlay('ImageRepeat.Y', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
381        Image($r('app.media.ic_public_favor_filled_1'))
382          .width(110)
383          .height(115)
384          .border({ width: 1 })
385          .objectRepeat(ImageRepeat.X)
386          .objectFit(ImageFit.ScaleDown)
387          // Repeat the image only along the horizontal axis.
388          .overlay('ImageRepeat.X', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
389      }
390    }.height(150).width('100%').padding(8)
391  }
392}
393```
394
395![en-us_image_0000001593444112](figures/en-us_image_0000001593444112.png)
396
397
398### Setting Image Rendering Mode
399
400You can use the **renderMode** attribute to set the rendering mode of an image.
401
402
403```ts
404@Entry
405@Component
406struct MyComponent {
407  build() {
408    Column({ space: 10 }) {
409      Row({ space: 50 }) {
410        Image($r('app.media.example'))
411          // Set the rendering mode to Original.
412          .renderMode(ImageRenderMode.Original)
413          .width(100)
414          .height(100)
415          .border({ width: 1 })
416            // overlay is a universal attribute, which is used to add overlay text on the component.
417          .overlay('Original', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
418        Image($r('app.media.example'))
419          // Set the rendering mode to Template.
420          .renderMode(ImageRenderMode.Template)
421          .width(100)
422          .height(100)
423          .border({ width: 1 })
424          .overlay('Template', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })
425      }
426    }.height(150).width('100%').padding({ top: 20,right: 10 })
427  }
428}
429```
430
431![en-us_image_0000001593293100](figures/en-us_image_0000001593293100.png)
432
433
434### Setting Image Decoding Size
435
436You can use the **sourceSize** attribute to set the image decoding size. By setting the decoding size to lower than the source size, you can decrease the image resolution.
437
438In this example, the source image size is 1280 x 960, and the decoding sizes are 40 x 40 and 90 x 90.
439
440
441```ts
442@Entry
443@Component
444struct Index {
445  build() {
446    Column() {
447      Row({ space: 50 }) {
448        Image($r('app.media.example'))
449          .sourceSize({
450            width: 40,
451            height: 40
452          })
453          .objectFit(ImageFit.ScaleDown)
454          .aspectRatio(1)
455          .width('25%')
456          .border({ width: 1 })
457          .overlay('width:40 height:40', { align: Alignment.Bottom, offset: { x: 0, y: 40 } })
458        Image($r('app.media.example'))
459          .sourceSize({
460            width: 90,
461            height: 90
462          })
463          .objectFit(ImageFit.ScaleDown)
464          .width('25%')
465          .aspectRatio(1)
466          .border({ width: 1 })
467          .overlay('width:90 height:90', { align: Alignment.Bottom, offset: { x: 0, y: 40 } })
468      }.height(150).width('100%').padding(20)
469    }
470  }
471}
472```
473
474![en-us_image_0000001593769844](figures/en-us_image_0000001593769844.png)
475
476
477### Adding a Filter to an Image
478
479You can use the **colorFilter** attribute to add a filter to an image.
480
481
482```ts
483@Entry
484@Component
485struct Index {
486  build() {
487    Column() {
488      Row() {
489        Image($r('app.media.example'))
490          .width('40%')
491          .margin(10)
492        Image($r('app.media.example'))
493          .width('40%')
494          .colorFilter(
495            [1, 1, 0, 0, 0,
496             0, 1, 0, 0, 0,
497             0, 0, 1, 0, 0,
498             0, 0, 0, 1, 0])
499          .margin(10)
500      }.width('100%')
501      .justifyContent(FlexAlign.Center)
502    }
503  }
504}
505```
506
507![en-us_image_0000001643171357](figures/en-us_image_0000001643171357.png)
508
509
510### Synchronously Loading Images
511
512Generally, the image loading process is performed asynchronously to avoid blocking the main thread and to streamline UI interaction. In certain cases, however, the image may flicker when refreshed. If this occurs, you can use the **syncLoad** attribute to load the image synchronously to avoid flickering. Avoid using this attribute if the image loading may take a long time. Otherwise, the page may fail to respond.
513
514
515```ts
516Image($r('app.media.icon'))
517  .syncLoad(true)
518```
519
520
521## Adding Events
522
523By binding the **onComplete** event to the **\<Image>** component, you can obtain necessary information about the image after the image is successfully loaded. You can also bind the **onError** event to obtain error information when the image fails to be loaded.
524
525
526```ts
527@Entry
528@Component
529struct MyComponent {
530  @State widthValue: number = 0
531  @State heightValue: number = 0
532  @State componentWidth: number = 0
533  @State componentHeight: number = 0
534
535  build() {
536    Column() {
537      Row() {
538        Image($r('app.media.ic_img_2'))
539          .width(200)
540          .height(150)
541          .margin(15)
542          .onComplete(msg => {
543            if(msg){
544              this.widthValue = msg.width
545              this.heightValue = msg.height
546              this.componentWidth = msg.componentWidth
547              this.componentHeight = msg.componentHeight
548            }
549          })
550            // If the image fails to be obtained, print the result.
551          .onError(() => {
552            console.info('load image fail')
553          })
554          .overlay('\nwidth: ' + String(this.widthValue) + ', height: ' + String(this.heightValue) + '\ncomponentWidth: ' + String(this.componentWidth) + '\ncomponentHeight: ' + String(this.componentHeight), {
555            align: Alignment.Bottom,
556            offset: { x: 0, y: 60 }
557          })
558      }
559    }
560  }
561}
562```
563
564
565![en-us_image_0000001511740460](figures/en-us_image_0000001511740460.png)
566