1# Image 2 3The **\<Image>** component is used to render and display local and online images. 4 5> **NOTE** 6> 7> This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. 8 9 10## Required Permissions 11 12To use online images, the application must have the **ohos.permission.INTERNET** permission. For details about how to apply for a permission, see [Declaring Permissions](../../security/accesstoken-guidelines.md). 13 14 15## Child Components 16 17Not supported 18 19 20## APIs 21 22Image(src: string | PixelMap | Resource) 23 24Obtains an image from the specified source for subsequent rendering and display. 25 26Since API version 9, this API is supported in ArkTS widgets. 27 28**Parameters** 29 30| Name| Type | Mandatory| Description | 31| ------ | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 32| src | string\| [PixelMap](../apis/js-apis-image.md#pixelmap7) \| [Resource](ts-types.md#resource) | Yes | Image source. Both local and online images are supported.<br>When using an image referenced using a relative path, for example, **Image("common/test.jpg")**, the **\<Image>** component cannot be called across bundles or modules. Therefore, you are advised to use **\$r** to reference image resources that need to be used globally.<br>- The following image formats are supported: PNG, JPG, BMP, SVG, GIF.<br>\- Base64 strings are supported. The value format is data:image/[png\|jpeg\|bmp\|webp];base64,[base64 data], where [base64 data] is a Base64 string.<br/>\- Strings with the **datashare://** path prefix are supported, which are used to access the image path provided by a Data ability. Before loading images, the application must [request the required permissions](../../file-management/medialibrary-overview.md#requesting-permissions).<br/>\- Strings with the **file:///data/storage** prefix are supported, which are used to read image resources in the **files** folder in the installation directory of the application. Ensure that the application has the read permission to the files in the specified path.<br/>- ArkTS widgets do not support the **http://**, **datashare://**, or **file://data/storage** path prefixes.<br>- ArkTS widgets do not support the [PixelMap](../apis/js-apis-image.md#pixelmap7) type.| 33 34## Attributes 35 36In addition to the [universal attributes](ts-universal-attributes-size.md), the following attributes are supported. 37 38| Name | Type | Description | 39| --------------------- | ------------------------------------------------------- | ------------------------------------------------------------ | 40| alt | string \| [Resource](ts-types.md#resource)| Placeholder image displayed during loading. Local images are supported.<br>Since API version 9, this API is supported in ArkTS widgets.| 41| objectFit | [ImageFit](ts-appendix-enums.md#imagefit) | Image scale mode.<br>Default value: **ImageFit.Cover**<br>Since API version 9, this API is supported in ArkTS widgets.| 42| objectRepeat | [ImageRepeat](ts-appendix-enums.md#imagerepeat) | Whether the image is repeated.<br>Default value: **ImageRepeat.NoRepeat**<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br>This attribute is not applicable to SVG images.| 43| interpolation | [ImageInterpolation](#imageinterpolation) | Interpolation effect of the image. This attribute is intended to alleviate aliasing that occurs when a low-definition image is zoomed in.<br>Default value: **ImageInterpolation.None**<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br>This attribute is not applicable to SVG images.<br>This attribute is not applicable to **PixelMap** objects.| 44| renderMode | [ImageRenderMode](#imagerendermode) | Rendering mode of the image.<br>Default value: **ImageRenderMode.Original**<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br>This attribute is not applicable to SVG images.| 45| sourceSize | {<br>width: number,<br>height: number<br>} | Size of the decoded image. The original image is decoded into a **pixelMap** of the specified size, in px.<br>Since API version 9, this API is supported in ArkTS widgets.<br>**NOTE**<br>This attribute is not applicable to **PixelMap** objects or SVG images.| 46| matchTextDirection | boolean | Whether to display the image in the system language direction. When this parameter is set to true, the image is horizontally flipped in the right-to-left (RTL) language context.<br>Default value: **false**<br>Since API version 9, this API is supported in ArkTS widgets.| 47| fitOriginalSize | boolean | Whether to fit the component to the original size of the image source when the component size is not set.<br>Default value: **false**<br>Since API version 9, this API is supported in ArkTS widgets.| 48| fillColor | [ResourceColor](ts-types.md#resourcecolor) | Fill color. This attribute only applies to an SVG image. Once set, the fill color will replace that of the SVG image.<br>Since API version 9, this API is supported in ArkTS widgets.| 49| autoResize | boolean | Whether to resize the image source used for drawing based on the size of the display area during image decoding. This resizing can help reduce the memory usage.<br>Default value: **true**<br>Since API version 9, this API is supported in ArkTS widgets.| 50| syncLoad<sup>8+</sup> | boolean | Whether to load the image synchronously. By default, the image is loaded asynchronously. During synchronous loading, the UI thread is blocked and the placeholder diagram is not displayed.<br>Default value: **false**<br>Since API version 9, this API is supported in ArkTS widgets.| 51| copyOption<sup>9+</sup> | [CopyOptions](ts-appendix-enums.md#copyoptions9) | Whether the image can be copied. (SVG images cannot be copied.)<br>When **copyOption** is set to a value other than **CopyOptions.None**, the image can be copied in various manners, such as long pressing, right-clicking, or pressing Ctrl+C.<br>Default value: **CopyOptions.None**<br>This API is supported in ArkTS widgets.| 52| colorFilter<sup>9+</sup> | [ColorFilter](ts-types.md#colorfilter9) | Color filter of the image.<br>This API is supported in ArkTS widgets.| 53 54> **NOTE** 55> 56> To use shortcut keys to copy the image, the image must be in focus. To enable the image to gain focus, set both the **focusable** and **focusOnTouch** attributes to **true**. 57> For SVG images, only the following tags are included in the supported list: **svg**, **rect**, **circle**, **ellipse**, **path**, **line**, **polyline**, **polygon**, and **animate**. 58 59### ImageInterpolation 60 61Since API version 9, this API is supported in ArkTS widgets. 62 63| Name | Description | 64| ------ | ------------------------- | 65| None | Interpolation image data is not used. | 66| High | The interpolation image data is used at the high level, which may affect the image rendering speed.| 67| Medium | The interpolation image data is used at the medium level. | 68| Low | The interpolation image data is used at the low level. | 69 70### ImageRenderMode 71 72Since API version 9, this API is supported in ArkTS widgets. 73 74| Name | Description | 75| -------- | --------------------- | 76| Original | The image is rendered based on the original image, including the color. | 77| Template | The image is rendered as a template image, and its color is ignored.| 78 79## Events 80 81In addition to the [universal events](ts-universal-events-click.md), the following events are supported. 82 83| Name | Description | 84| ------------------------------------------------------------ | ------------------------------------------------------------ | 85| onComplete(callback: (event?: { width: number, height: number, componentWidth: number,<br> componentHeight: number, loadingStatus: number }) => void) | Triggered when an image is successfully loaded. The size of the loaded image is returned.<br>- **width**: width of the image, in pixels.<br>- **height**: height of the image, in pixels.<br>- **componentWidth**: width of the container component, in pixels.<br>- **componentHeight**: height of the container component, in pixels.<br>- **loadingStatus**: image loading status.<br>Since API version 9, this API is supported in ArkTS widgets.| 86| onError(callback: (event?: { componentWidth: number, componentHeight: number , message<sup>9+</sup>: string }) => void) | Triggered when an exception occurs during image loading.<br>- **componentWidth**: width of the container component, in pixels.<br>- **componentHeight**: height of the container component, in pixels.<br>Since API version 9, this API is supported in ArkTS widgets.| 87| onFinish(event: () => void) | Triggered when the animation playback in the loaded SVG image is complete. If the animation is an infinite loop, this callback is not triggered.<br>Since API version 9, this API is supported in ArkTS widgets.| 88 89## Example 90 91### Loading Images 92 93Load and display different types of images and set the scale mode of the images. 94 95```ts 96@Entry 97@Component 98struct ImageExample1 { 99 private on: string = 'www.example.com' 100 @State src: string = this.on 101 102 build() { 103 Column() { 104 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) { 105 Text('default').fontSize(16).fontColor(0xcccccc).height(30) 106 Row({ space: 5 }) { 107 Image($r('app.media.ic_png')) 108 .width(110).height(110).border({ width: 1 }) 109 .overlay('png', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 110 Image($r('app.media.ic_gif')) 111 .width(110).height(110).border({ width: 1 }) 112 .overlay('gif', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 113 Image($r('app.media.ic_svg')) 114 .width(110).height(110).border({ width: 1 }) 115 .overlay('svg', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 116 } 117 Row({ space: 5 }) { 118 Image($r('app.media.img_example')) 119 .width(110).height(110).border({ width: 1 }) 120 .overlay('jpg', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 121 Image(this.src) 122 .width(110).height(110).border({ width: 1 }) 123 .overlay('network', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 124 }.margin({ top: 25, bottom: 10 }) 125 } 126 127 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) { 128 Text('objectFit').fontSize(16).fontColor(0xcccccc).height(30) 129 Row({ space: 5 }) { 130 Image($r('app.media.img_example')) 131 .border({ width: 1 }) 132 .objectFit(ImageFit.None).width(110).height(110) 133 .overlay('None', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 134 Image($r('app.media.img_example')) 135 .border({ width: 1 }) 136 .objectFit(ImageFit.Fill).width(110).height(110) 137 .overlay('Fill', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 138 Image($r('app.media.img_example')) 139 .border({ width: 1 }) 140 .objectFit(ImageFit.Cover).width(110).height(110) 141 .overlay('Cover', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 142 } 143 Row({ space: 5 }) { 144 Image($r('app.media.img_example_w250')) 145 .border({ width: 1 }) 146 .objectFit(ImageFit.Contain).width(110).height(110) 147 .overlay('Contain', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 148 Image($r('app.media.img_example_w250')) 149 .border({ width: 1 }) 150 .objectFit(ImageFit.ScaleDown).width(110).height(110) 151 .overlay('ScaleDown', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 152 }.margin({ top: 25 }) 153 } 154 }.height(320).width(360).padding({ right: 10, top: 10 }) 155 } 156} 157``` 158 159 160 161 162 163### Loading Online Images 164 165The default network timeout period is 5 minutes for loading online images. When using an online image, you are advised to use **alt** to configure the placeholder image displayed during loading. If more flexible network configuration is required, use the [HTTP](../../connectivity/http-request.md) module in the SDK to send a network request, and then decode the returned data into a **PixelMap** in the **\<Image>** component. For details about image development, see [Image Development](../../media/image.md). The code snippet is as follows: 166 167```tsx 168// @ts-nocheck 169import http from '@ohos.net.http' 170import ResponseCode from '@ohos.net.http' 171import image from '@ohos.multimedia.image' 172 173 174@Entry 175@Component 176struct Index { 177 178 // Create a PixelMap state variable to receive online images. 179 @State image: PixelMap = undefined 180 181 build() { 182 Column({space: 10}) { 183 Button ("Get Online Image") 184 .onClick(() => { 185 this.httpRequest() 186 }) 187 Image(this.image).height(100).width(100) 188 } 189 .width('100%') 190 .height('100%') 191 .padding(10) 192 } 193 194 // Request an online image. 195 private httpRequest() { 196 let httpRequest = http.createHttp() 197 198 httpRequest.request( 199 "https://www.example.com/xxx.png", // Enter a specific URL of the online image. 200 (error, data) => { 201 if(error) { 202 console.log("error code: " + error.code + ", msg: " + error.message) 203 } else { 204 let code = data.responseCode 205 if(ResponseCode.ResponseCode.OK == code) { 206 let imageSource = image.createImageSource(data.result) 207 let options = {alphaType: 0, // Opacity 208 editable: false, // Whether the image is editable 209 pixelFormat: 3, // Pixel format 210 scaleMode: 1, // Scale mode 211 size: {height: 100, width: 100}} // Image size 212 imageSource.createPixelMap(options).then((pixelMap) => { 213 this.image = pixelMap 214 }) 215 } else { 216 console.log("response code: " + code) 217 } 218 } 219 } 220 ) 221 } 222} 223``` 224 225> **NOTE** 226> 227> For details about the request mode, timeout, and additional request parameters for loading online images, see [request()](../../reference/apis/js-apis-http.md) in the HTTP module. 228 229### Setting Attributes 230 231```ts 232@Entry 233@Component 234struct ImageExample2 { 235 236 build() { 237 Column({ space: 10 }) { 238 Text('renderMode').fontSize(12).fontColor(0xcccccc).width('96%').height(30) 239 Row({ space: 50 }) { 240 Image($r('app.media.img_example')) 241 .renderMode(ImageRenderMode.Original).width(100).height(100) 242 .border({ width: 1 }) 243 .overlay('Original', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 244 Image($r('app.media.img_example')) 245 .renderMode(ImageRenderMode.Template).width(100).height(100) 246 .border({ width: 1 }) 247 .overlay('Template', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 248 } 249 250 Text('alt').fontSize(12).fontColor(0xcccccc).width('96%').height(30) 251 Image('') 252 .alt($r('app.media.Image_none')) 253 .width(100).height(100).border({ width: 1 }) 254 255 Text('sourceSize').fontSize(12).fontColor(0xcccccc).width('96%') 256 Row({ space: 50 }) { 257 Image($r('app.media.img_example')) 258 .sourceSize({ 259 width: 150, 260 height: 150 261 }) 262 .objectFit(ImageFit.ScaleDown).width('25%').aspectRatio(1) 263 .border({ width: 1 }) 264 .overlay('w:150 h:150', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 265 Image($r('app.media.img_example')) 266 .sourceSize({ 267 width: 200, 268 height: 200 269 }) 270 .objectFit(ImageFit.ScaleDown).width('25%').aspectRatio(1) 271 .border({ width: 1 }) 272 .overlay('w:200 h:200', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 273 } 274 275 Text('objectRepeat').fontSize(12).fontColor(0xcccccc).width('96%').height(30) 276 Row({ space: 5 }) { 277 Image($r('app.media.ic_health_heart')) 278 .width(120).height(125).border({ width: 1 }) 279 .objectRepeat(ImageRepeat.XY).objectFit(ImageFit.ScaleDown) 280 .overlay('ImageRepeat.XY', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 281 Image($r('app.media.ic_health_heart')) 282 .width(110).height(125).border({ width: 1 }) 283 .objectRepeat(ImageRepeat.Y).objectFit(ImageFit.ScaleDown) 284 .overlay('ImageRepeat.Y', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 285 Image($r('app.media.ic_health_heart')) 286 .width(110).height(125).border({ width: 1 }) 287 .objectRepeat(ImageRepeat.X).objectFit(ImageFit.ScaleDown) 288 .overlay('ImageRepeat.X', { align: Alignment.Bottom, offset: { x: 0, y: 20 } }) 289 } 290 }.height(150).width('100%').padding({ right: 10 }) 291 } 292} 293``` 294 295 296 297### Invoking Events 298 299```ts 300@Entry 301@Component 302struct ImageExample3 { 303 @State widthValue: number = 0 304 @State heightValue: number = 0 305 private on: Resource = $r('app.media.image_on') 306 private off: Resource = $r('app.media.image_off') 307 private on2off: Resource = $r('app.media.image_on2off') 308 private off2on: Resource = $r('app.media.image_off2on') 309 @State src: Resource = this.on 310 311 build() { 312 Column() { 313 Row({ space: 20 }) { 314 Column() { 315 Image($r('app.media.img_example1')) 316 .alt($r('app.media.ic_public_picture')) 317 .sourceSize({ 318 width: 900, 319 height: 900 320 }) 321 .objectFit(ImageFit.Cover) 322 .height(180).width(180) 323 // Obtain the size of an image after the image loading is complete. 324 .onComplete((msg: { width: number,height: number }) => { 325 this.widthValue = msg.width 326 this.heightValue = msg.height 327 }) 328 .onError(() => { 329 console.log('load image fail') 330 }) 331 .overlay('\nwidth: ' + String(this.widthValue) + ' height: ' + String(this.heightValue), { 332 align: Alignment.Bottom, 333 offset: { x: 0, y: 20 } 334 }) 335 } 336 // Add a click event so that a specific image is loaded upon clicking. 337 Image(this.src) 338 .width(120).height(120) 339 .onClick(() => { 340 if (this.src == this.on || this.src == this.off2on) { 341 this.src = this.on2off 342 } else { 343 this.src = this.off2on 344 } 345 }) 346 .onFinish(() => { 347 if (this.src == this.off2on) { 348 this.src = this.on 349 } else { 350 this.src = this.off 351 } 352 }) 353 } 354 }.width('100%') 355 } 356} 357``` 358 359 360 361### Rendering Sandbox Images 362 363```ts 364import fileio from '@ohos.fileio'; 365import fs from '@ohos.file.fs'; 366import context from '@ohos.app.ability.common'; 367 368@Entry 369@Component 370struct LoadImageExample { 371 @State resourcesPath: string = '' 372 @State sandboxPath: string = '' 373 context: context.UIAbility = getContext(this) as context.UIAbilityContext 374 375 build() { 376 Column() { 377 Button ('Read Sandbox Image') 378 .margin({ bottom: 10, top: 10 }) 379 .onClick(() => { 380 this.sandboxPath = this.context.getApplicationContext().filesDir + '/icon.png' 381 console.log(`Read the sandbox image=========>${this.sandboxPath}`) 382 let fd = fs.openSync(this.sandboxPath, 0o100) 383 console.log(`create file========>${fd}`) 384 let srcPath = this.context.bundleCodeDir + '/entry/resources/base/media/icon.png' 385 console.log('mySrcpath' + srcPath) 386 fileio.copyFileSync(srcPath, this.sandboxPath) // Copy the image to the sandbox path. 387 this.sandboxPath = 'file://' + this.context.getApplicationContext().filesDir + '/icon.png' 388 }) 389 Button ('Read Image') 390 .margin({ bottom: 10 }) 391 .onClick(() => { 392 this.resourcesPath = 'file://' + this.context.bundleCodeDir + '/entry/resources/base/media/icon.png' 393 }) 394 Text(`Image path: ${this.resourcesPath}`) 395 .fontSize(20) 396 .margin({ bottom: 10 }) 397 Image(this.resourcesPath) 398 .width(100) 399 .height(100) 400 Text(`Sandbox image path: ${this.sandboxPath}`) 401 .fontSize(20) 402 .margin({ bottom: 10 }) 403 Image(this.sandboxPath) 404 .width(100) 405 .height(100) 406 } 407 .width('100%').height('100%') 408 } 409} 410``` 411