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  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')) 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 237 238 **Figure 4** SVG image after the fill color is set 239 240 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 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 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 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 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 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 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 566