• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }) =&gt; 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 }) =&gt; 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: () =&gt; 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![en-us_image_0000001211898484](figures/en-us_image_0000001211898484.gif)
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![en-us_image_0000001212058474](figures/en-us_image_0000001212058474.png)
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![en-us_image_0000001256858397](figures/en-us_image_0000001256858397.gif)
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