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