1e41f4b71Sopenharmony_ci# PhotoEditorExtensionContext
2e41f4b71Sopenharmony_ci**PhotoEditorExtensionContext**, which inherits from **ExtensionContext**, provides the context environment for the PhotoEditorExtensionAbility. It provides PhotoEditorExtensionAbility related configuration and APIs for saving images.
3e41f4b71Sopenharmony_ci> **NOTE**
4e41f4b71Sopenharmony_ci> 
5e41f4b71Sopenharmony_ci> The initial APIs of this module are supported since API version 12. Newly added APIs will be marked with a superscript to indicate their earliest API version.
6e41f4b71Sopenharmony_ci> 
7e41f4b71Sopenharmony_ci> The APIs of this module can be used only in the stage model.
8e41f4b71Sopenharmony_ci> 
9e41f4b71Sopenharmony_ci> The APIs of this module must be used in the main thread, but not in sub-threads such as Worker and TaskPool.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci## Modules to Import
12e41f4b71Sopenharmony_ci```ts
13e41f4b71Sopenharmony_ciimport { common } from '@kit.AbilityKit';
14e41f4b71Sopenharmony_ci```
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci## PhotoEditorExtensionContext.saveEditedContentWithUri
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_cisaveEditedContentWithUri(uri: string): Promise\<AbilityResult\>
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ciSaves an edited image, which is passed in through a URI.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci**Model restriction**: This API can be used only in the stage model.
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci**System capability**: SystemCapability.Ability.AppExtension.PhotoEditorExtension
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci**Parameters**
27e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description |
28e41f4b71Sopenharmony_ci| ------------ | ------------ | ------------ | ------------ |
29e41f4b71Sopenharmony_ci| uri | string  | Yes | [URI](../apis-core-file-kit/js-apis-file-fileuri.md) of the edited image. The format is file://\<bundleName>/\<sandboxPath>. |
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci**Return value**
32e41f4b71Sopenharmony_ci|  Type| Description |
33e41f4b71Sopenharmony_ci| ------------ | ------------ |
34e41f4b71Sopenharmony_ci| Promise\<AbilityResult\> | Promise used to return an **AbilityResult** object. The URI of the edited image is stored in **want.uri**. The [URI](../apis-core-file-kit/js-apis-file-fileuri.md) format is file://\<bundleName>/\<sandboxPath>. |
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci**Error codes**
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ciFor details about the error codes, see [Universal Error Codes](../errorcode-universal.md) and [Ability Error Codes](errorcode-ability.md).
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci|  ID| Error Message |
41e41f4b71Sopenharmony_ci| ------------ | ------------ |
42e41f4b71Sopenharmony_ci| 401  | Params error. Possible causes: 1.Mandatory parameters are left unspecified. 2.Incorrect parameter types.  |
43e41f4b71Sopenharmony_ci| 29600001  | Internal error. |
44e41f4b71Sopenharmony_ci| 29600002  |  Image input error. |
45e41f4b71Sopenharmony_ci| 29600003  |  Image too big. |
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci**Example**
48e41f4b71Sopenharmony_ci```ts
49e41f4b71Sopenharmony_ciimport { common, UIExtensionContentSession, Want } from '@kit.AbilityKit';
50e41f4b71Sopenharmony_ciimport { hilog } from '@kit.PerformanceAnalysisKit';
51e41f4b71Sopenharmony_ciimport { fileIo } from '@kit.CoreFileKit';
52e41f4b71Sopenharmony_ciimport { image } from '@kit.ImageKit';
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ciconst TAG = '[ExamplePhotoEditorAbility]';
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ci@Entry
57e41f4b71Sopenharmony_ci@Component
58e41f4b71Sopenharmony_cistruct Index {
59e41f4b71Sopenharmony_ci  // Original image
60e41f4b71Sopenharmony_ci  @State originalImage: PixelMap | null = null;
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci  build() {
63e41f4b71Sopenharmony_ci    Row() {
64e41f4b71Sopenharmony_ci      Column() {
65e41f4b71Sopenharmony_ci        Button("RotateAndSaveImg").onClick(event => {
66e41f4b71Sopenharmony_ci          hilog.info(0x0000, TAG, `Start to edit image and save.`);
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci          this.originalImage?.rotate(90).then(() => {
69e41f4b71Sopenharmony_ci            const imagePackerApi: image.ImagePacker = image.createImagePacker();
70e41f4b71Sopenharmony_ci            let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 };
71e41f4b71Sopenharmony_ci            imagePackerApi.packing(this.originalImage, packOpts).then((data: ArrayBuffer) => {
72e41f4b71Sopenharmony_ci              let context = getContext(this) as common.PhotoEditorExtensionContext;
73e41f4b71Sopenharmony_ci              let filePath = context.filesDir + "/edited.jpg";
74e41f4b71Sopenharmony_ci              let file: fileIo.File | undefined;
75e41f4b71Sopenharmony_ci              try{
76e41f4b71Sopenharmony_ci                file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE
77e41f4b71Sopenharmony_ci                | fileIo.OpenMode.CREATE | fileIo.OpenMode.TRUNC);
78e41f4b71Sopenharmony_ci                let writeLen = fileIo.writeSync(file.fd, data);
79e41f4b71Sopenharmony_ci                hilog.info(0x0000, TAG, "write data to file succeed and size is:"
80e41f4b71Sopenharmony_ci                  + writeLen);
81e41f4b71Sopenharmony_ci                fileIo.closeSync(file);
82e41f4b71Sopenharmony_ci                context.saveEditedContentWithUri(filePath).then
83e41f4b71Sopenharmony_ci                  (data => {
84e41f4b71Sopenharmony_ci                    hilog.info(0x0000, TAG,
85e41f4b71Sopenharmony_ci                      `saveContentEditingWithUri result: ${JSON.stringify(data)}`);
86e41f4b71Sopenharmony_ci                  });
87e41f4b71Sopenharmony_ci              } catch (e) {
88e41f4b71Sopenharmony_ci                hilog.info(0x0000, TAG, `writeImage failed:${e}`);
89e41f4b71Sopenharmony_ci              } finally {
90e41f4b71Sopenharmony_ci                fileIo.close(file);
91e41f4b71Sopenharmony_ci              }
92e41f4b71Sopenharmony_ci            }).catch((error: BusinessError) => {
93e41f4b71Sopenharmony_ci              hilog.error(0x0000, TAG,
94e41f4b71Sopenharmony_ci                'Failed to pack the image. And the error is: ' + String(error));
95e41f4b71Sopenharmony_ci            })
96e41f4b71Sopenharmony_ci          })
97e41f4b71Sopenharmony_ci        }).margin({ top: 10 })
98e41f4b71Sopenharmony_ci      }
99e41f4b71Sopenharmony_ci    }
100e41f4b71Sopenharmony_ci  }
101e41f4b71Sopenharmony_ci}
102e41f4b71Sopenharmony_ci```
103e41f4b71Sopenharmony_ci## PhotoEditorExtensionContext.saveEditedContentWithImage
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_cisaveEditedContentWithImage(pixeMap: image.PixelMap, option: image.PackingOption): Promise\<AbilityResult\>
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ciSaves an edited image, which is passed in through a **PixelMap** object.
108e41f4b71Sopenharmony_ci
109e41f4b71Sopenharmony_ci**Model restriction**: This API can be used only in the stage model.
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci**System capability**: SystemCapability.Ability.AppExtension.PhotoEditorExtension
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ci**Parameters**
114e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description |
115e41f4b71Sopenharmony_ci| ------------ | ------------ | ------------ | ------------ |
116e41f4b71Sopenharmony_ci| pixeMap | [image.PixelMap](../apis-image-kit/js-apis-image.md#pixelmap7)  | Yes | Edited image, which is an **image.PixelMap** object. |
117e41f4b71Sopenharmony_ci| option  | [image.PackingOption](..//apis-image-kit/js-apis-image.md#packingoption)  |  Yes| Option for image packing. |
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci**Return value**
120e41f4b71Sopenharmony_ci|  Type| Description |
121e41f4b71Sopenharmony_ci| ------------ | ------------ |
122e41f4b71Sopenharmony_ci| Promise\<AbilityResult\> | Promise used to return an **AbilityResult** object. The URI of the edited image is stored in **want.uri**. The [URI](../apis-core-file-kit/js-apis-file-fileuri.md) format is file://\<bundleName>/\<sandboxPath>. |
123e41f4b71Sopenharmony_ci
124e41f4b71Sopenharmony_ci**Error codes**
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ciFor details about the error codes, see [Universal Error Codes](../errorcode-universal.md) and [Ability Error Codes](errorcode-ability.md).
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_ci|  ID| Error Message |
129e41f4b71Sopenharmony_ci| ------------ | ------------ |
130e41f4b71Sopenharmony_ci| 401  | Params error. Possible causes: 1.Mandatory parameters are left unspecified. 2.Incorrect parameter types.  |
131e41f4b71Sopenharmony_ci| 29600001  | Internal error. |
132e41f4b71Sopenharmony_ci| 29600002  |  Image input error. |
133e41f4b71Sopenharmony_ci| 29600003  |  Image too big. |
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ci**Example**
136e41f4b71Sopenharmony_ci```ts
137e41f4b71Sopenharmony_ciimport { common, UIExtensionContentSession, Want } from '@kit.AbilityKit';
138e41f4b71Sopenharmony_ciimport { hilog } from '@kit.PerformanceAnalysisKit';
139e41f4b71Sopenharmony_ciimport { image } from '@kit.ImageKit';
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ciconst TAG = '[ExamplePhotoEditorAbility]';
142e41f4b71Sopenharmony_ci
143e41f4b71Sopenharmony_ci@Entry
144e41f4b71Sopenharmony_ci@Component
145e41f4b71Sopenharmony_cistruct Index {
146e41f4b71Sopenharmony_ci  // Original image
147e41f4b71Sopenharmony_ci  @State originalImage: PixelMap | null = null;
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci  build() {
150e41f4b71Sopenharmony_ci    Row() {
151e41f4b71Sopenharmony_ci      Column() {
152e41f4b71Sopenharmony_ci        Button("RotateAndSaveImg").onClick(event => {
153e41f4b71Sopenharmony_ci          hilog.info(0x0000, TAG, `Start to edit image and save.`);
154e41f4b71Sopenharmony_ci
155e41f4b71Sopenharmony_ci          this.originalImage?.rotate(90).then(() => {
156e41f4b71Sopenharmony_ci            let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 };
157e41f4b71Sopenharmony_ci            try {
158e41f4b71Sopenharmony_ci              let context = getContext(this) as common.PhotoEditorExtensionContext;
159e41f4b71Sopenharmony_ci              context.saveEditedContentWithImage(this.originalImage as image.PixelMap,
160e41f4b71Sopenharmony_ci                packOpts).then(data => {
161e41f4b71Sopenharmony_ci                  hilog.info(0x0000, TAG,
162e41f4b71Sopenharmony_ci                    `saveContentEditingWithImage result: ${JSON.stringify(data)}`);
163e41f4b71Sopenharmony_ci                });
164e41f4b71Sopenharmony_ci            } catch (e) {
165e41f4b71Sopenharmony_ci              hilog.error(0x0000, TAG, `saveContentEditingWithImage failed:${e}`);
166e41f4b71Sopenharmony_ci              return;
167e41f4b71Sopenharmony_ci            }
168e41f4b71Sopenharmony_ci          })
169e41f4b71Sopenharmony_ci        }).margin({ top: 10 })
170e41f4b71Sopenharmony_ci      }
171e41f4b71Sopenharmony_ci    }
172e41f4b71Sopenharmony_ci  }
173e41f4b71Sopenharmony_ci}
174e41f4b71Sopenharmony_ci```
175