From 5c54275aec3605150fcf0e098b3eda7cc4b2001d Mon Sep 17 00:00:00 2001 From: Nick Pomfret Date: Thu, 6 Apr 2017 07:28:47 +0100 Subject: [PATCH] android jpeg compression support (#658) * * removed some of the re-parsing of the output image byte array * removed re-saving of output file * moved image processing onto an async task to allow camera to be used while processing is running * added jpeg compression support for android * move explanation to correct bit of docs --- README.md | 1 + .../lwansbrough/RCTCamera/MutableImage.java | 25 +++---------------- .../RCTCamera/RCTCameraModule.java | 13 +++++++--- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index f96b08d..89c3d47 100644 --- a/README.md +++ b/README.md @@ -300,6 +300,7 @@ Supported options: - `metadata` This is metadata to be added to the captured image. - `location` This is the object returned from `navigator.geolocation.getCurrentPosition()` (React Native's geolocation polyfill). It will add GPS metadata to the image. - `rotation` This will rotate the image by the number of degrees specified. + - `jpegQuality` (integer between 1 and 100) This property is used to compress the output jpeg file with 100% meaning no jpeg compression will be applied. The promise will be fulfilled with an object with some of the following properties: diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/MutableImage.java b/android/src/main/java/com/lwansbrough/RCTCamera/MutableImage.java index cbf4336..dc9da45 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/MutableImage.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/MutableImage.java @@ -20,7 +20,6 @@ import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; @@ -135,13 +134,13 @@ public class MutableImage { } } - public String toBase64() { - return Base64.encodeToString(toBytes(currentRepresentation), Base64.DEFAULT); + public String toBase64(int jpegQualityPercent) { + return Base64.encodeToString(toJpeg(currentRepresentation, jpegQualityPercent), Base64.DEFAULT); } - public void writeDataToFile(File file, ReadableMap options) throws IOException { + public void writeDataToFile(File file, ReadableMap options, int jpegQualityPercent) throws IOException { FileOutputStream fos = new FileOutputStream(file); - fos.write(toBytes(currentRepresentation)); + fos.write(toJpeg(currentRepresentation, jpegQualityPercent)); fos.close(); try { @@ -205,22 +204,6 @@ public class MutableImage { return originalImageMetaData; } - private static byte[] toBytes(Bitmap image) { - byte[] result = null; - - try { - result = toJpeg(image, 85); - } catch (OutOfMemoryError e) { - try { - result = toJpeg(image, 70); - } catch (OutOfMemoryError e2) { - e.printStackTrace(); - } - } - - return result; - } - private static byte[] toJpeg(Bitmap bitmap, int quality) throws OutOfMemoryError { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream); diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java index a06c0b5..251b730 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java @@ -575,9 +575,14 @@ public class RCTCameraModule extends ReactContextBaseJavaModule promise.reject("Error mirroring image", e); } + int jpegQualityPercent = 80; + if(options.hasKey("jpegQuality")) { + jpegQualityPercent = options.getInt("jpegQuality"); + } + switch (options.getInt("target")) { case RCT_CAMERA_CAPTURE_TARGET_MEMORY: - String encoded = mutableImage.toBase64(); + String encoded = mutableImage.toBase64(jpegQualityPercent); WritableMap response = new WritableNativeMap(); response.putString("data", encoded); promise.resolve(response); @@ -590,7 +595,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule } try { - mutableImage.writeDataToFile(cameraRollFile, options); + mutableImage.writeDataToFile(cameraRollFile, options, jpegQualityPercent); } catch (IOException e) { promise.reject("failed to save image file", e); return; @@ -610,7 +615,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule } try { - mutableImage.writeDataToFile(pictureFile, options); + mutableImage.writeDataToFile(pictureFile, options, 85); } catch (IOException e) { promise.reject("failed to save image file", e); return; @@ -628,7 +633,7 @@ public class RCTCameraModule extends ReactContextBaseJavaModule } try { - mutableImage.writeDataToFile(tempFile, options); + mutableImage.writeDataToFile(tempFile, options, 85); } catch (IOException e) { promise.reject("failed to save image file", e); return;