44 * This source code is licensed under the MIT license found in the
55 * LICENSE file in the root directory of this source tree.
66 */
7-
87package com .reactnativecommunity .imageeditor ;
98
109import javax .annotation .Nullable ;
1817import java .net .URL ;
1918import java .net .URLConnection ;
2019import java .util .Arrays ;
21- import java .util .Collections ;
2220import java .util .List ;
23- import java .util .Map ;
2421
2522import android .annotation .SuppressLint ;
2623import android .content .ContentResolver ;
4340import com .facebook .react .bridge .ReactApplicationContext ;
4441import com .facebook .react .bridge .ReactContext ;
4542import com .facebook .react .bridge .ReactContextBaseJavaModule ;
46- import com .facebook .react .bridge .ReactMethod ;
4743import com .facebook .react .bridge .JSApplicationIllegalArgumentException ;
4844import com .facebook .react .bridge .ReadableMap ;
4945import com .facebook .infer .annotation .Assertions ;
5046import com .facebook .react .common .ReactConstants ;
5147
52- /**
53- * Native module that provides image cropping functionality.
54- */
55- public class ImageEditorModule extends ReactContextBaseJavaModule {
48+ public class ImageEditorModuleImpl {
49+ private ReactApplicationContext reactContext ;
5650
5751 protected static final String NAME = "RNCImageEditor" ;
5852
5953 private static final List <String > LOCAL_URI_PREFIXES = Arrays .asList (
60- ContentResolver .SCHEME_FILE ,
61- ContentResolver .SCHEME_CONTENT ,
62- ContentResolver .SCHEME_ANDROID_RESOURCE
54+ ContentResolver .SCHEME_FILE ,
55+ ContentResolver .SCHEME_CONTENT ,
56+ ContentResolver .SCHEME_ANDROID_RESOURCE
6357 );
6458
6559 private static final String TEMP_FILE_PREFIX = "ReactNative_cropped_image_" ;
@@ -95,24 +89,13 @@ public class ImageEditorModule extends ReactContextBaseJavaModule {
9589 ExifInterface .TAG_WHITE_BALANCE
9690 };
9791
98- public ImageEditorModule (ReactApplicationContext reactContext ) {
99- super (reactContext );
100- new CleanTask (getReactApplicationContext ()).executeOnExecutor (AsyncTask .THREAD_POOL_EXECUTOR );
101- }
102-
103- @ Override
104- public String getName () {
105- return NAME ;
106- }
107-
108- @ Override
109- public Map <String , Object > getConstants () {
110- return Collections .emptyMap ();
92+ public ImageEditorModuleImpl (ReactApplicationContext context ) {
93+ reactContext = context ;
94+ new CleanTask (reactContext ).executeOnExecutor (AsyncTask .THREAD_POOL_EXECUTOR );
11195 }
11296
113- @ Override
11497 public void onCatalystInstanceDestroy () {
115- new CleanTask (getReactApplicationContext () ).executeOnExecutor (AsyncTask .THREAD_POOL_EXECUTOR );
98+ new CleanTask (reactContext ).executeOnExecutor (AsyncTask .THREAD_POOL_EXECUTOR );
11699 }
117100
118101 /**
@@ -139,12 +122,12 @@ protected void doInBackgroundGuarded(Void... params) {
139122
140123 private void cleanDirectory (File directory ) {
141124 File [] toDelete = directory .listFiles (
142- new FilenameFilter () {
143- @ Override
144- public boolean accept (File dir , String filename ) {
145- return filename .startsWith (TEMP_FILE_PREFIX );
146- }
147- });
125+ new FilenameFilter () {
126+ @ Override
127+ public boolean accept (File dir , String filename ) {
128+ return filename .startsWith (TEMP_FILE_PREFIX );
129+ }
130+ });
148131 if (toDelete != null ) {
149132 for (File file : toDelete ) {
150133 file .delete ();
@@ -166,30 +149,29 @@ public boolean accept(File dir, String filename) {
166149 * @param promise Promise to be resolved when the image has been cropped; the only argument that
167150 * is passed to this is the file:// URI of the new image
168151 */
169- @ ReactMethod
170152 public void cropImage (
171- String uri ,
172- ReadableMap options ,
173- Promise promise ) {
153+ String uri ,
154+ ReadableMap options ,
155+ Promise promise ) {
174156 ReadableMap offset = options .hasKey ("offset" ) ? options .getMap ("offset" ) : null ;
175157 ReadableMap size = options .hasKey ("size" ) ? options .getMap ("size" ) : null ;
176158 if (offset == null || size == null ||
177- !offset .hasKey ("x" ) || !offset .hasKey ("y" ) ||
178- !size .hasKey ("width" ) || !size .hasKey ("height" )) {
159+ !offset .hasKey ("x" ) || !offset .hasKey ("y" ) ||
160+ !size .hasKey ("width" ) || !size .hasKey ("height" )) {
179161 throw new JSApplicationIllegalArgumentException ("Please specify offset and size" );
180162 }
181163 if (uri == null || uri .isEmpty ()) {
182164 throw new JSApplicationIllegalArgumentException ("Please specify a URI" );
183165 }
184166
185167 CropTask cropTask = new CropTask (
186- getReactApplicationContext () ,
187- uri ,
188- (int ) offset .getDouble ("x" ),
189- (int ) offset .getDouble ("y" ),
190- (int ) size .getDouble ("width" ),
191- (int ) size .getDouble ("height" ),
192- promise );
168+ reactContext ,
169+ uri ,
170+ (int ) offset .getDouble ("x" ),
171+ (int ) offset .getDouble ("y" ),
172+ (int ) size .getDouble ("width" ),
173+ (int ) size .getDouble ("height" ),
174+ promise );
193175 if (options .hasKey ("displaySize" )) {
194176 ReadableMap targetSize = options .getMap ("displaySize" );
195177 cropTask .setTargetSize (
@@ -211,17 +193,17 @@ private static class CropTask extends GuardedAsyncTask<Void, Void> {
211193 final Promise mPromise ;
212194
213195 private CropTask (
214- ReactContext context ,
215- String uri ,
216- int x ,
217- int y ,
218- int width ,
219- int height ,
220- Promise promise ) {
196+ ReactContext context ,
197+ String uri ,
198+ int x ,
199+ int y ,
200+ int width ,
201+ int height ,
202+ Promise promise ) {
221203 super (context );
222204 if (x < 0 || y < 0 || width <= 0 || height <= 0 ) {
223205 throw new JSApplicationIllegalArgumentException (String .format (
224- "Invalid crop rectangle: [%d, %d, %d, %d]" , x , y , width , height ));
206+ "Invalid crop rectangle: [%d, %d, %d, %d]" , x , y , width , height ));
225207 }
226208 mContext = context ;
227209 mUri = uri ;
@@ -235,7 +217,7 @@ private CropTask(
235217 public void setTargetSize (int width , int height ) {
236218 if (width <= 0 || height <= 0 ) {
237219 throw new JSApplicationIllegalArgumentException (String .format (
238- "Invalid target size: [%d, %d]" , width , height ));
220+ "Invalid target size: [%d, %d]" , width , height ));
239221 }
240222 mTargetWidth = width ;
241223 mTargetHeight = height ;
@@ -314,10 +296,10 @@ private Bitmap crop(BitmapFactory.Options outOptions) throws IOException {
314296 * @param outOptions Bitmap options, useful to determine {@code outMimeType}.
315297 */
316298 private Bitmap cropAndResize (
317- int targetWidth ,
318- int targetHeight ,
319- BitmapFactory .Options outOptions )
320- throws IOException {
299+ int targetWidth ,
300+ int targetHeight ,
301+ BitmapFactory .Options outOptions )
302+ throws IOException {
321303 Assertions .assertNotNull (outOptions );
322304
323305 // Loading large bitmaps efficiently:
@@ -450,7 +432,7 @@ private static Bitmap.CompressFormat getCompressFormatForType(String type) {
450432 }
451433
452434 private static void writeCompressedBitmapToFile (Bitmap cropped , String mimeType , File tempFile )
453- throws IOException {
435+ throws IOException {
454436 OutputStream out = new FileOutputStream (tempFile );
455437 try {
456438 cropped .compress (getCompressFormatForType (mimeType ), COMPRESS_QUALITY , out );
@@ -468,7 +450,7 @@ private static void writeCompressedBitmapToFile(Bitmap cropped, String mimeType,
468450 * @param mimeType the MIME type of the file to create (image/*)
469451 */
470452 private static File createTempFile (Context context , @ Nullable String mimeType )
471- throws IOException {
453+ throws IOException {
472454 File externalCacheDir = context .getExternalCacheDir ();
473455 File internalCacheDir = context .getCacheDir ();
474456 File cacheDir ;
@@ -482,7 +464,7 @@ else if (internalCacheDir == null) {
482464 cacheDir = externalCacheDir ;
483465 } else {
484466 cacheDir = externalCacheDir .getFreeSpace () > internalCacheDir .getFreeSpace () ?
485- externalCacheDir : internalCacheDir ;
467+ externalCacheDir : internalCacheDir ;
486468 }
487469 return File .createTempFile (TEMP_FILE_PREFIX , getFileExtensionForType (mimeType ), cacheDir );
488470 }
@@ -499,7 +481,7 @@ private static int getDecodeSampleSize(int width, int height, int targetWidth, i
499481 int halfHeight = height / 2 ;
500482 int halfWidth = width / 2 ;
501483 while ((halfWidth / inSampleSize ) >= targetWidth
502- && (halfHeight / inSampleSize ) >= targetHeight ) {
484+ && (halfHeight / inSampleSize ) >= targetHeight ) {
503485 inSampleSize *= 2 ;
504486 }
505487 }
0 commit comments