Add support for base64 formatted Uri strings on Android. (#47)

This commit is contained in:
Chris Fogelklou 2016-09-22 08:18:06 +02:00 committed by Florian Rival
parent af2a09e1d8
commit 8a485bf0a9
3 changed files with 60 additions and 7 deletions

View File

@ -48,7 +48,7 @@ The promise resolves with a string containing the uri of the new file.
Option | Description Option | Description
------ | ----------- ------ | -----------
path | Path of image path | Path of image file, or a base64 encoded image string prefixed with 'data:image/<imagetype>' where <imagetype> is jpeg or png.
maxWidth | Image max width (ratio is preserved) maxWidth | Image max width (ratio is preserved)
maxHeight | Image max height (ratio is preserved) maxHeight | Image max height (ratio is preserved)
compressFormat | Can be either JPEG, PNG or WEBP (android only). compressFormat | Can be either JPEG, PNG or WEBP (android only).

View File

@ -12,6 +12,7 @@ import android.net.Uri;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Base64;
import android.util.Pair; import android.util.Pair;
import java.io.Closeable; import java.io.Closeable;
@ -28,6 +29,8 @@ import java.util.Date;
*/ */
class ImageResizer { class ImageResizer {
private final static String BASE64_PREFIX = "data:image/";
/** /**
* Resize the specified bitmap, keeping its aspect ratio. * Resize the specified bitmap, keeping its aspect ratio.
*/ */
@ -202,11 +205,10 @@ class ImageResizer {
} }
/** /**
* Create a resized version of the given image. * Loads the bitmap resource from the file specified in imagePath.
*/ */
public static String createResizedImage(Context context, String imagePath, int newWidth, private static Bitmap loadBitmapFromFile(Context context, String imagePath, int newWidth,
int newHeight, Bitmap.CompressFormat compressFormat, int newHeight) throws IOException {
int quality, int rotation, String outputPath) throws IOException {
// Decode the image bounds to find the size of the source image. // Decode the image bounds to find the size of the source image.
BitmapFactory.Options options = new BitmapFactory.Options(); BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; options.inJustDecodeBounds = true;
@ -216,7 +218,55 @@ class ImageResizer {
options.inSampleSize = calculateInSampleSize(options, newWidth, newHeight); options.inSampleSize = calculateInSampleSize(options, newWidth, newHeight);
options.inJustDecodeBounds = false; options.inJustDecodeBounds = false;
System.out.println(options.inSampleSize); System.out.println(options.inSampleSize);
Bitmap sourceImage = loadBitmap(context, imagePath, options); return loadBitmap(context, imagePath, options);
}
/**
* Loads the bitmap resource from a base64 encoded jpg or png.
* Format is as such:
* png: 'data:image/png;base64,iVBORw0KGgoAA...'
* jpg: 'data:image/jpeg;base64,/9j/4AAQSkZJ...'
*/
private static Bitmap loadBitmapFromBase64(String imagePath) {
Bitmap sourceImage = null;
// base64 image. Convert to a bitmap.
final int prefixLen = BASE64_PREFIX.length();
final boolean isJpeg = (imagePath.indexOf("jpeg") == prefixLen);
final boolean isPng = (!isJpeg) && (imagePath.indexOf("png") == prefixLen);
int commaLocation = -1;
if (isJpeg || isPng){
commaLocation = imagePath.indexOf(',');
}
if (commaLocation > 0) {
final String encodedImage = imagePath.substring(commaLocation+1);
final byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
sourceImage = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
}
return sourceImage;
}
/**
* Create a resized version of the given image.
*/
public static String createResizedImage(Context context, String imagePath, int newWidth,
int newHeight, Bitmap.CompressFormat compressFormat,
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) {
sourceImage = ImageResizer.loadBitmapFromFile(context, imagePath, newWidth, newHeight);
}
else {
sourceImage = ImageResizer.loadBitmapFromBase64(imagePath);
}
if (sourceImage == null){
return "";
}
// Scale it first so there are fewer pixels to transform in the rotation // Scale it first so there are fewer pixels to transform in the rotation
Bitmap scaledImage = ImageResizer.resizeImage(sourceImage, newWidth, newHeight); Bitmap scaledImage = ImageResizer.resizeImage(sourceImage, newWidth, newHeight);

View File

@ -45,7 +45,10 @@ class ImageResizerModule extends ReactContextBaseJavaModule {
String compressFormatString, int quality, int rotation, String outputPath, String compressFormatString, int quality, int rotation, String outputPath,
final Callback successCb, final Callback failureCb) throws IOException { final Callback successCb, final Callback failureCb) throws IOException {
Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.valueOf(compressFormatString); Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.valueOf(compressFormatString);
imagePath = imagePath.replace("file:", ""); if (imagePath.indexOf("data:image/") < 0) {
imagePath = imagePath.replace("file:", "");
}
String resizedImagePath = ImageResizer.createResizedImage(this.context, imagePath, newWidth, String resizedImagePath = ImageResizer.createResizedImage(this.context, imagePath, newWidth,
newHeight, compressFormat, quality, rotation, outputPath); newHeight, compressFormat, quality, rotation, outputPath);