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