@@ -62,72 +62,58 @@ interface EditorResult {
62
62
base64 ?: string
63
63
}
64
64
65
- const context = getContext ( this ) as common . ApplicationContext
66
-
67
- let newOptions : ImageCropData = {
68
- offset : { x : 0 , y : 0 } ,
69
- size : { width : 0 , height : 0 } ,
70
- resizeMode : 'cover' ,
71
- includeBase64 : false ,
72
- }
73
-
74
- let resizeScaleSize : size = {
75
- width : 0 ,
76
- height : 0
77
- }
78
-
79
65
async function loadBase ( uri : string ) {
80
66
return new Promise ( ( resolve ) => {
81
67
let buf = buffer . alloc ( uri . length , uri )
82
68
resolve ( buf . buffer )
83
69
} )
84
70
}
71
+
85
72
function loadHttp ( uri : string ) {
86
73
return new Promise ( ( resolve , reject ) => {
87
74
http . createHttp ( ) . request ( uri , {
88
75
header : {
89
76
'Content-Type' : 'application/octet-stream'
90
77
}
91
78
} ,
92
- async ( error : BusinessError , data : http . HttpResponse ) => {
93
- let code : http . ResponseCode | number = data . responseCode
94
- if ( ResponseCode . ResponseCode . OK === code ) {
95
- const imageData = data . result as ArrayBuffer
96
- Logger . info ( "http.createHttp success" )
97
- resolve ( imageData )
98
- } else {
99
- Logger . error ( "http.createHttp error is " + error )
100
- }
101
- } )
79
+ async ( error : BusinessError , data : http . HttpResponse ) => {
80
+ let code : http . ResponseCode | number = data . responseCode
81
+ if ( ResponseCode . ResponseCode . OK === code ) {
82
+ const imageData = data . result as ArrayBuffer
83
+ Logger . info ( "http.createHttp success" )
84
+ resolve ( imageData )
85
+ } else {
86
+ Logger . error ( "http.createHttp error is " + error )
87
+ }
88
+ } )
102
89
} )
103
90
}
104
91
105
- async function getUriBuffer ( uri : string ) {
106
- let imageBuffer = null
92
+ async function imageEditor ( newOptions :ImageCropData , uri : string ) : Promise < EditorResult > {
93
+ let imageData = null
94
+ let openFile = null
107
95
if ( uri . startsWith ( "data:" ) ) {
108
- imageBuffer = await loadBase ( uri )
96
+ imageData = await loadBase ( uri )
109
97
} else if ( uri . startsWith ( 'http' ) ) {
110
- imageBuffer = await loadHttp ( uri )
98
+ imageData = await loadHttp ( uri )
111
99
} else {
112
- imageBuffer = uri
100
+ openFile = fs . openSync ( uri , fs . OpenMode . READ_ONLY )
101
+ imageData = openFile . fd
113
102
}
114
- return imageBuffer
115
- }
116
103
117
- async function imageEditor ( imageData ) : Promise < EditorResult > {
118
104
let imageSourceApi : image . ImageSource = image . createImageSource ( imageData )
119
105
let getImageInfo : image . ImageInfo
120
106
let options : Record < string , number | boolean > = {
121
107
'editable' : true ,
122
108
}
123
- let editorPM = await imageSourceApi . createPixelMap ( options )
109
+ let editorPM = await imageSourceApi . createPixelMap ( options )
124
110
125
111
editorPM . getImageInfo ( ) . then ( ( imageInfo : image . ImageInfo ) => {
126
- if ( newOptions . offset . x + newOptions . size . width > imageInfo . size . width || newOptions . offset . y + newOptions . size . height > imageInfo . size . height ) {
112
+ if ( newOptions . offset . x + newOptions . size . width > imageInfo . size . width || newOptions . offset . y + newOptions . size . height > imageInfo . size . height ) {
127
113
Logger . error ( '[RNOH]:The cropped size exceeds the original size' )
128
114
return
129
115
}
130
- } )
116
+ } )
131
117
132
118
const x = newOptions . offset . x
133
119
const y = newOptions . offset . y
@@ -136,24 +122,24 @@ async function imageEditor(imageData): Promise<EditorResult> {
136
122
let region : image . Region = { x, y, size : { height, width} }
137
123
138
124
await editorPM . crop ( region ) . then ( ( ) => {
139
- Logger . info ( 'imageEditor.Succeeded in crop.' ) ;
140
- } ) . catch ( ( error : BusinessError ) => {
141
- Logger . error ( 'imageEditor.Failed to crop.' ) ;
142
- } )
125
+ Logger . info ( 'imageEditor.Succeeded in crop.' )
126
+ } ) . catch ( ( error : BusinessError ) => {
127
+ Logger . error ( 'imageEditor.Failed to crop.' )
128
+ } )
143
129
144
130
if ( newOptions . displaySize && newOptions . displaySize . width && newOptions . displaySize . height ) {
145
-
146
131
const cropSize = newOptions . size
147
132
const displaySize = JSON . parse ( JSON . stringify ( newOptions . displaySize ) )
148
133
const aspect = cropSize . width / cropSize . height
149
134
const targetAspect = displaySize . width / displaySize . height
150
135
if ( aspect === targetAspect ) newOptions . resizeMode = 'stretch'
151
-
136
+
152
137
const xRatio = displaySize . width / cropSize . width
153
138
const yRatio = displaySize . height / cropSize . height
154
139
if ( newOptions . resizeMode === 'stretch' ) {
155
140
await editorPM . scale ( xRatio , yRatio )
156
141
} else if ( newOptions . resizeMode === 'cover' ) {
142
+ let resizeScaleSize : size = displaySize
157
143
if ( displaySize . width !== cropSize . width || displaySize . height !== cropSize . height ) {
158
144
const ratio = Math . max ( xRatio , yRatio )
159
145
await editorPM . scale ( ratio , ratio )
@@ -163,40 +149,42 @@ async function imageEditor(imageData): Promise<EditorResult> {
163
149
} )
164
150
}
165
151
166
- const targetRegion = await TargetRect ( )
152
+ const targetRegion = await TargetRect ( newOptions , resizeScaleSize )
167
153
await editorPM . crop ( targetRegion ) . then ( ( ) => {
168
- Logger . info ( 'imageEditor.Succeeded in crop.' ) ;
154
+ Logger . info ( 'imageEditor.Succeeded in crop.' )
169
155
} ) . catch ( ( error : BusinessError ) => {
170
- Logger . error ( 'imageEditor.Failed to crop.' ) ;
156
+ Logger . error ( 'imageEditor.Failed to crop.' )
171
157
} )
172
-
173
158
} else {
174
- const { size } = await TargetRect ( )
159
+ const { size } = await TargetRect ( newOptions )
175
160
const xRatio = size . width / cropSize . width
176
161
const yRatio = size . height / cropSize . height
177
162
await editorPM . scale ( xRatio , yRatio )
178
163
}
179
-
180
164
}
181
165
await editorPM . getImageInfo ( ) . then ( ( imageInfo : image . ImageInfo ) => {
182
- getImageInfo = imageInfo
183
- } )
184
-
166
+ getImageInfo = imageInfo
167
+ } )
168
+ let context = getContext ( this ) as common . ApplicationContext
185
169
let suffix = newOptions . format
186
170
suffix = suffix === 'jpeg' || suffix === 'jpg' ? 'jpeg' : suffix
187
171
const fileName = `ReactNative_cropped_image_${ new Date ( ) . getTime ( ) } .${ suffix === 'jpeg' ?'jpg' :suffix } `
188
172
const path : string = `${ context . cacheDir } /${ fileName } `
189
173
let packOpts : image . PackingOption = { format : `image/${ suffix } ` , quality : newOptions . quality || 90 }
190
- let file = await fs . openSync ( path , fs . OpenMode . CREATE | fs . OpenMode . READ_WRITE ) ;
191
174
let size = 0
192
175
let base64Data = ''
193
176
194
177
const imagePackerApi :image . ImagePacker = image . createImagePacker ( )
195
178
await imagePackerApi . packing ( editorPM , packOpts )
196
179
. then ( async ( data : ArrayBuffer ) => {
197
- let writeLen = await fs . writeSync ( file . fd , data )
198
- size = writeLen
199
- fs . closeSync ( file )
180
+ let file = fs . openSync ( path , fs . OpenMode . CREATE | fs . OpenMode . READ_WRITE )
181
+ try {
182
+ size = fs . writeSync ( file . fd , data )
183
+ } catch ( err ) {
184
+ Logger . error ( 'file write failed' )
185
+ } finally {
186
+ fs . closeSync ( file )
187
+ }
200
188
201
189
if ( newOptions . includeBase64 ) {
202
190
let unit8Array : Uint8Array = new Uint8Array ( data )
@@ -205,14 +193,15 @@ async function imageEditor(imageData): Promise<EditorResult> {
205
193
}
206
194
207
195
} ) . catch ( ( error : BusinessError ) => {
208
- Logger . error ( 'packing failed.' ) ;
196
+ Logger . error ( 'packing failed.' )
197
+ } ) . finally ( ( ) => {
198
+ openFile && fs . closeSync ( openFile )
209
199
} )
210
200
211
201
editorPM . release ( )
212
202
imageSourceApi . release ( )
213
203
imagePackerApi . release ( )
214
-
215
- size = await fs . statSync ( path ) . size ;
204
+ context = null
216
205
217
206
const result :EditorResult = {
218
207
uri : `file://${ path } ` ,
@@ -226,10 +215,10 @@ async function imageEditor(imageData): Promise<EditorResult> {
226
215
if ( newOptions . includeBase64 ) {
227
216
result . base64 = base64Data
228
217
}
229
- return result ;
218
+ return result
230
219
}
231
220
232
- async function TargetRect ( ) {
221
+ async function TargetRect ( newOptions : ImageCropData , resizeScaleSize ?: size ) {
233
222
const resizeMode = newOptions . resizeMode
234
223
const cropSize = newOptions . size
235
224
const displaySize = JSON . parse ( JSON . stringify ( newOptions . displaySize ) )
@@ -255,17 +244,18 @@ async function TargetRect() {
255
244
targetSize . height = displaySize . height
256
245
targetSize . width = Math . ceil ( targetSize . height * aspect )
257
246
}
247
+ targetRegion . size = targetSize
258
248
} else if ( resizeMode === 'center' ) {
259
249
if ( cropSize . height > displaySize . height ) {
260
250
targetSize . width = displaySize . width
261
251
targetSize . height = Math . ceil ( targetSize . width / aspect )
262
- }
252
+ }
263
253
if ( cropSize . width > displaySize . width ) {
264
254
targetSize . height = displaySize . height
265
255
targetSize . width = Math . ceil ( targetSize . height * aspect )
266
256
}
257
+ targetRegion . size = targetSize
267
258
}
268
- targetRegion . size = targetSize
269
259
return targetRegion
270
260
}
271
261
@@ -278,18 +268,18 @@ export class ImageEditorModule extends TurboModule {
278
268
quality = Math . floor ( options . quality * 100 )
279
269
}
280
270
if ( ! uri ) {
281
- Logger . warn ( '[RNOH]:Please specify a URI' ) ;
271
+ Logger . warn ( '[RNOH]:Please specify a URI' )
282
272
return
283
273
}
284
274
if ( ! offset || ! size || ! ( 'x' in offset ) || ! ( 'y' in offset ) || ! size . width || ! size . height ) {
285
- Logger . warn ( '[RNOH]:Please specify offset and size' ) ;
275
+ Logger . warn ( '[RNOH]:Please specify offset and size' )
286
276
return
287
277
}
288
278
if ( quality > 100 || quality < 0 ) {
289
- Logger . warn ( '[RNOH]:quality must be a number between 0 and 1' ) ;
279
+ Logger . warn ( '[RNOH]:quality must be a number between 0 and 1' )
290
280
return
291
281
}
292
-
282
+ let newOptions : ImageCropData = options
293
283
newOptions . size = size
294
284
newOptions . offset = offset
295
285
newOptions . quality = quality
@@ -303,10 +293,7 @@ export class ImageEditorModule extends TurboModule {
303
293
}
304
294
if ( options . includeBase64 ) newOptions . includeBase64 = options . includeBase64
305
295
306
- const buffer = await getUriBuffer ( uri )
307
- const fileUri : EditorResult = await imageEditor ( buffer )
308
-
296
+ const fileUri : EditorResult = await imageEditor ( newOptions , uri )
309
297
return fileUri . uri
310
-
311
298
}
312
- }
299
+ }
0 commit comments