Skip to content

Commit 53f1763

Browse files
committed
feature: Convert a uri crop result to an object
1 parent 4ce8d89 commit 53f1763

File tree

6 files changed

+61
-17
lines changed

6 files changed

+61
-17
lines changed

README.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,21 @@ Crop the image specified by the URI param. If URI points to a remote image, it w
3939
If the cropping process is successful, the resultant cropped image will be stored in the cache path, and the URI returned in the promise will point to the image in the cache path. Remember to delete the cropped image from the cache path when you are done with it.
4040

4141
```ts
42-
ImageEditor.cropImage(uri, cropData).then((url) => {
43-
console.log('Cropped image uri', url);
44-
// In case of Web, the `url` is the base64 string
45-
});
42+
ImageEditor.cropImage(uri, cropData).then(
43+
({
44+
uri, // the path to the image file (example: 'file:///data/user/0/.../image.jpg')
45+
path, // the URI of the image (example: '/data/user/0/.../image.jpg')
46+
name, // the name of the image file. (example: 'image.jpg')
47+
width, // the width of the image in pixels
48+
height, // height of the image in pixels
49+
size, // the size of the image in bytes
50+
}) => {
51+
console.log('Cropped image uri:', uri);
52+
// WEB has different response:
53+
// - `uri` is the base64 string (example `data:image/jpeg;base64,/4AAQ...AQABAA`)
54+
// - `path` is the blob URL (example `blob:https://example.com/43ff7a16...e46b1`)
55+
}
56+
);
4657
```
4758

4859
### `cropData: ImageCropData`

example/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ PODS:
807807
- React-jsinspector (0.72.6)
808808
- React-logger (0.72.6):
809809
- glog
810-
- react-native-image-editor (3.1.0):
810+
- react-native-image-editor (3.2.0):
811811
- RCT-Folly (= 2021.07.22.00)
812812
- RCTRequired
813813
- RCTTypeSafety
@@ -1129,7 +1129,7 @@ SPEC CHECKSUMS:
11291129
React-jsiexecutor: faca9c368233f59ed24601aca0185870466a96e9
11301130
React-jsinspector: 194e32c6aab382d88713ad3dd0025c5f5c4ee072
11311131
React-logger: cebf22b6cf43434e471dc561e5911b40ac01d289
1132-
react-native-image-editor: a58ef0223f36bd9b8aa5c2b9d45926ce51946e50
1132+
react-native-image-editor: ed27495b9a98482d6f4642c42b165dfe23523b8d
11331133
React-NativeModulesApple: 63505fb94b71e2469cab35bdaf36cca813cb5bfd
11341134
React-perflogger: e3596db7e753f51766bceadc061936ef1472edc3
11351135
React-RCTActionSheet: 17ab132c748b4471012abbcdcf5befe860660485

example/src/SquareImageCropper.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,12 @@ export class SquareImageCropper extends Component<Props, State> {
131131
if (!this._transformData) {
132132
return;
133133
}
134-
const croppedImageURI = await ImageEditor.cropImage(
134+
const { uri } = await ImageEditor.cropImage(
135135
this.state.photo.uri,
136136
this._transformData
137137
);
138-
if (croppedImageURI) {
139-
this.setState({ croppedImageURI });
138+
if (uri) {
139+
this.setState({ croppedImageURI: uri });
140140
}
141141
} catch (cropError) {
142142
if (cropError instanceof Error) {

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import { Platform } from 'react-native';
99
import NativeRNCImageEditor from './NativeRNCImageEditor';
1010
import type { Spec } from './NativeRNCImageEditor';
11-
import type { ImageCropData } from './types.ts';
11+
import type { ImageCropData, CropResult } from './types.ts';
1212

1313
const LINKING_ERROR =
1414
`The package '@react-native-community/image-editor' doesn't seem to be linked. Make sure: \n\n` +
@@ -37,7 +37,7 @@ class ImageEditor {
3737
* will point to the image in the cache path. Remember to delete the
3838
* cropped image from the cache path when you are done with it.
3939
*/
40-
static cropImage(uri: string, cropData: ImageCropData): Promise<string> {
40+
static cropImage(uri: string, cropData: ImageCropData): CropResult {
4141
return RNCImageEditor.cropImage(uri, cropData);
4242
}
4343
}

src/index.web.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ImageCropData } from './types.ts';
1+
import type { ImageCropData, CropResult } from './types.ts';
22

33
function drawImage(
44
img: HTMLImageElement,
@@ -51,16 +51,47 @@ function fetchImage(imgSrc: string): Promise<HTMLImageElement> {
5151
const DEFAULT_COMPRESSION_QUALITY = 0.9;
5252

5353
class ImageEditor {
54-
static cropImage(imgSrc: string, cropData: ImageCropData): Promise<string> {
54+
static cropImage(imgSrc: string, cropData: ImageCropData): CropResult {
5555
/**
5656
* Returns a promise that resolves with the base64 encoded string of the cropped image
5757
*/
5858
return fetchImage(imgSrc).then(function onfulfilledImgToCanvas(image) {
59+
const ext = cropData.format ?? 'jpeg';
60+
const type = `image/${ext}`;
61+
const quality = cropData.quality ?? DEFAULT_COMPRESSION_QUALITY;
5962
const canvas = drawImage(image, cropData);
60-
return canvas.toDataURL(
61-
`image/${cropData.format ?? 'jpeg'}`,
62-
cropData.quality ?? DEFAULT_COMPRESSION_QUALITY
63-
);
63+
64+
return new Promise<Blob | null>(function onfulfilledCanvasToBlob(
65+
resolve
66+
) {
67+
canvas.toBlob(resolve, type, quality);
68+
}).then((blob) => {
69+
if (!blob) {
70+
throw new Error('Image cannot be created from canvas');
71+
}
72+
73+
let _path: string, _uri: string;
74+
75+
return {
76+
width: canvas.width,
77+
height: canvas.height,
78+
name: 'ReactNative_cropped_image.' + ext,
79+
size: blob.size,
80+
// Lazy getters to avoid unnecessary memory usage
81+
get path() {
82+
if (!_path) {
83+
_path = URL.createObjectURL(blob);
84+
}
85+
return _path;
86+
},
87+
get uri() {
88+
if (!_uri) {
89+
_uri = canvas.toDataURL(type, quality);
90+
}
91+
return _uri;
92+
},
93+
};
94+
});
6495
});
6596
}
6697
}

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ export interface ImageCropData
99
// ^^^ codegen doesn't support union types yet
1010
// so to provide more type safety we override the type here
1111
}
12+
13+
export type CropResult = ReturnType<Spec['cropImage']>;

0 commit comments

Comments
 (0)