diff --git a/.gitignore b/.gitignore index 69f8209..9cabefb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ -node_modules -workbench -*.log -# Xcode +# OSX +# .DS_Store + +# Xcode +# build/ *.pbxuser !default.pbxuser @@ -12,10 +13,45 @@ build/ !default.mode2v3 *.perspectivev3 !default.perspectivev3 -*.xcworkspace -!default.xcworkspace xcuserdata -profile +*.xccheckout *.moved-aside DerivedData -.idea/ +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml + +# node.js +# +node_modules/ +npm-debug.log + +# BUCK +buck-out/ +\.buckd/ +android/app/libs +*.keystore + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots + + +# APK +android/app/*.apk diff --git a/android/build.gradle b/android/build.gradle index 00c7390..cf868b9 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,3 +1,14 @@ +buildscript { + repositories { + jcenter() + } + + + dependencies { + classpath 'com.android.tools.build:gradle:2.2.3' + } +} + apply plugin: 'com.android.library' android { @@ -17,6 +28,10 @@ android { } } +repositories { + mavenCentral() +} + dependencies { compile 'com.facebook.react:react-native:+' } diff --git a/android/src/main/java/fr/bamlab/rnimageresizer/ImageResizer.java b/android/src/main/java/fr/bamlab/rnimageresizer/ImageResizer.java index b8a066d..3654d43 100644 --- a/android/src/main/java/fr/bamlab/rnimageresizer/ImageResizer.java +++ b/android/src/main/java/fr/bamlab/rnimageresizer/ImageResizer.java @@ -29,7 +29,9 @@ import java.util.Date; */ class ImageResizer { - private final static String BASE64_PREFIX = "data:image/"; + public final static String BASE64_PREFIX = "data:image/"; + public final static String CONTENT_PREFIX = "content://"; + public final static String FILE_PREFIX = "file:"; /** * Resize the specified bitmap, keeping its aspect ratio. @@ -188,11 +190,20 @@ class ImageResizer { /** * Load a bitmap either from a real file or using the {@link ContentResolver} of the current * {@link Context} (to read gallery images for example). + * + * Note that, when options.inJustDecodeBounds = true, we actually expect sourceImage to remain + * as null (see https://developer.android.com/training/displaying-bitmaps/load-bitmap.html), so + * getting null sourceImage at the completion of this method is not always worthy of an error. */ private static Bitmap loadBitmap(Context context, String imagePath, BitmapFactory.Options options) throws IOException { Bitmap sourceImage = null; - if (!imagePath.startsWith("content://") && !imagePath.startsWith("file://")) { - sourceImage = BitmapFactory.decodeFile(imagePath, options); + if (!imagePath.startsWith(CONTENT_PREFIX)) { + try { + sourceImage = BitmapFactory.decodeFile(imagePath, options); + } catch (Exception e) { + e.printStackTrace(); + throw new IOException("Error decoding image file"); + } } else { ContentResolver cr = context.getContentResolver(); InputStream input = cr.openInputStream(Uri.parse(imagePath)); @@ -256,16 +267,16 @@ class ImageResizer { int quality, int rotation, String outputPath) throws IOException { Bitmap sourceImage = null; - // If the BASE64_PREFIX is absent, load bitmap from a file. Otherwise, load from base64. - if (imagePath.indexOf(BASE64_PREFIX) < 0) { + // If the BASE64_PREFIX is absent, load bitmap from a file. Otherwise, load from base64. + if (!imagePath.startsWith(BASE64_PREFIX)) { sourceImage = ImageResizer.loadBitmapFromFile(context, imagePath, newWidth, newHeight); } else { sourceImage = ImageResizer.loadBitmapFromBase64(imagePath); } - if (sourceImage == null){ - return ""; + if (sourceImage == null) { + throw new IOException("Unable to load source image from path"); } // Scale it first so there are fewer pixels to transform in the rotation diff --git a/android/src/main/java/fr/bamlab/rnimageresizer/ImageResizerModule.java b/android/src/main/java/fr/bamlab/rnimageresizer/ImageResizerModule.java index 15da182..0922293 100644 --- a/android/src/main/java/fr/bamlab/rnimageresizer/ImageResizerModule.java +++ b/android/src/main/java/fr/bamlab/rnimageresizer/ImageResizerModule.java @@ -45,13 +45,19 @@ class ImageResizerModule extends ReactContextBaseJavaModule { String compressFormatString, int quality, int rotation, String outputPath, final Callback successCb, final Callback failureCb) throws IOException { Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.valueOf(compressFormatString); - if (imagePath.indexOf("data:image/") < 0) { - imagePath = imagePath.replace("file:", ""); + if (imagePath.startsWith(ImageResizer.FILE_PREFIX)) { + imagePath = imagePath.replaceFirst(ImageResizer.FILE_PREFIX, ""); } String resizedImagePath = ImageResizer.createResizedImage(this.context, imagePath, newWidth, newHeight, compressFormat, quality, rotation, outputPath); - successCb.invoke("file:" + resizedImagePath); + // If resizedImagePath is empty and this wasn't caught earlier, throw. + if (resizedImagePath == null || resizedImagePath.isEmpty()) { + throw new IOException("Error getting resized image path"); + } + + // Invoke success, prepending file prefix. + successCb.invoke(ImageResizer.FILE_PREFIX + resizedImagePath); } } diff --git a/example/android/app/app.iml b/example/android/app/app.iml deleted file mode 100644 index 5efe8d3..0000000 --- a/example/android/app/app.iml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/example/android/app/src/main/java/com/resizerexample/MainApplication.java b/example/android/app/src/main/java/com/resizerexample/MainApplication.java index c9d6fdc..d841481 100644 --- a/example/android/app/src/main/java/com/resizerexample/MainApplication.java +++ b/example/android/app/src/main/java/com/resizerexample/MainApplication.java @@ -17,7 +17,7 @@ public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override - protected boolean getUseDeveloperSupport() { + public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } diff --git a/example/package.json b/example/package.json index 7e17c5a..863209f 100644 --- a/example/package.json +++ b/example/package.json @@ -6,9 +6,9 @@ "start": "node node_modules/react-native/local-cli/cli.js start" }, "dependencies": { - "react": "^15.2.1", - "react-native": "^0.31.0", + "react": "^15.4.0", + "react-native": "^0.41.0", "react-native-gifted-spinner": "0.0.4", - "react-native-image-resizer": "^0.0.8" + "react-native-image-resizer": "file:../" } } diff --git a/package.json b/package.json index 3b08999..4b6dfb2 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "resize" ], "peerDependencies": { - "react-native": ">=v0.14.2" + "react": "^15.4.0", + "react-native": ">=v0.40.0" }, "author": "Florian Rival (http://bam.tech)", "license": "MIT",