From dd49879fdda615ebcfa3d82ecd0e30fc3c8ffe87 Mon Sep 17 00:00:00 2001 From: Malik Kawee <> Date: Tue, 21 Apr 2020 18:56:15 +0500 Subject: [PATCH 1/4] #Fixed image rotation issue on samsung(S) devices --- .../rnsketchcanvas/SketchCanvas.java | 108 ++++++++++++++++-- 1 file changed, 101 insertions(+), 7 deletions(-) diff --git a/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java b/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java index a67fb4f1..a5108e9b 100644 --- a/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java +++ b/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java @@ -1,5 +1,6 @@ package com.terrylinla.rnsketchcanvas; +import android.graphics.Matrix; import android.graphics.Typeface; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -9,6 +10,8 @@ import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.Rect; +import android.media.ExifInterface; +import android.net.Uri; import android.os.Environment; import android.util.Base64; import android.util.Log; @@ -24,6 +27,8 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; import java.util.ArrayList; class CanvasText { @@ -52,6 +57,7 @@ public class SketchCanvas extends View { private int mOriginalWidth, mOriginalHeight; private Bitmap mBackgroundImage; private String mContentMode; + private Uri backgroundURI; private ArrayList mArrCanvasText = new ArrayList(); private ArrayList mArrTextOnSketch = new ArrayList(); @@ -68,14 +74,29 @@ public boolean openImageFile(String filename, String directory, String mode) { filename.lastIndexOf('.') == -1 ? filename : filename.substring(0, filename.lastIndexOf('.')), "drawable", mContext.getPackageName()); + File file = new File(filename, directory == null ? "" : directory); BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); - Bitmap bitmap = res == 0 ? - BitmapFactory.decodeFile(new File(filename, directory == null ? "" : directory).toString(), bitmapOptions) : + Bitmap bitmap = res == 0 ? + BitmapFactory.decodeFile(file.toString(), bitmapOptions) : BitmapFactory.decodeResource(mContext.getResources(), res); if(bitmap != null) { - mBackgroundImage = bitmap; - mOriginalHeight = bitmap.getHeight(); - mOriginalWidth = bitmap.getWidth(); + backgroundURI = Uri.fromFile(file); + + + ExifInterface exif = null; + try { + exif = new ExifInterface(backgroundURI.getPath()); + } catch (IOException e) { + e.printStackTrace(); + } + + int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); + + Bitmap newBitmap = rotateBitmap(bitmap, orientation); + + mBackgroundImage = newBitmap; + mOriginalHeight = newBitmap.getHeight(); + mOriginalWidth = newBitmap.getWidth(); mContentMode = mode; invalidateCanvas(true); @@ -336,6 +357,7 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { protected void onDraw(Canvas canvas) { super.onDraw(canvas); + if (mNeedsFullRedraw && mDrawingCanvas != null) { mDrawingCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY); for(SketchData path: mPaths) { @@ -345,10 +367,12 @@ protected void onDraw(Canvas canvas) { } if (mBackgroundImage != null) { + Rect dstRect = new Rect(); canvas.getClipBounds(dstRect); - canvas.drawBitmap(mBackgroundImage, null, - Utility.fillImage(mBackgroundImage.getWidth(), mBackgroundImage.getHeight(), dstRect.width(), dstRect.height(), mContentMode), + + canvas.drawBitmap(mBackgroundImage, null, + Utility.fillImage(mBackgroundImage.getWidth(), mBackgroundImage.getHeight(), dstRect.width(), dstRect.height(), mContentMode), null); } @@ -357,6 +381,7 @@ protected void onDraw(Canvas canvas) { } if (mDrawingBitmap != null) { + canvas.drawBitmap(mDrawingBitmap, 0, 0, mPaint); } @@ -381,11 +406,80 @@ private void invalidateCanvas(boolean shouldDispatchEvent) { invalidate(); } + private static Bitmap rotateBitmap(Bitmap bitmap, int orientation) { + Matrix matrix = new Matrix(); + switch (orientation) { + case ExifInterface.ORIENTATION_NORMAL: + return bitmap; + case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: + matrix.setScale(-1, 1); + break; + case ExifInterface.ORIENTATION_ROTATE_180: + matrix.setRotate(180); + break; + case ExifInterface.ORIENTATION_FLIP_VERTICAL: + matrix.setRotate(180); + matrix.postScale(-1, 1); + break; + case ExifInterface.ORIENTATION_TRANSPOSE: + matrix.setRotate(90); + matrix.postScale(-1, 1); + break; + case ExifInterface.ORIENTATION_ROTATE_90: + matrix.setRotate(90); + break; + case ExifInterface.ORIENTATION_TRANSVERSE: + matrix.setRotate(-90); + matrix.postScale(-1, 1); + break; + case ExifInterface.ORIENTATION_ROTATE_270: + matrix.setRotate(-90); + break; + default: + return bitmap; + } + try { + Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); + bitmap.recycle(); + + return bmRotated; + } catch (OutOfMemoryError e) { + e.printStackTrace(); + return null; + } + } + +// public static void normalizeImageForUri(Context context, Uri uri) { +// try { +// Log.d("normalize", "URI value = " + uri.getPath()); +// ExifInterface exif = new ExifInterface(uri.getPath()); +// Log.d("normalize", "Exif value = " + exif); +// int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); +// Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri); +// Bitmap rotatedBitmap = rotateBitmap(bitmap, orientation); +// if (!bitmap.equals(rotatedBitmap)) { +// saveBitmapToFile(context, rotatedBitmap, uri); +// } +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } + private Bitmap createImage(boolean transparent, boolean includeImage, boolean includeText, boolean cropToImageSize) { Bitmap bitmap = Bitmap.createBitmap( mBackgroundImage != null && cropToImageSize ? mOriginalWidth : getWidth(), mBackgroundImage != null && cropToImageSize ? mOriginalHeight : getHeight(), Bitmap.Config.ARGB_8888); + ExifInterface exif = null; + try { + exif = new ExifInterface(backgroundURI.getPath()); + } catch (IOException e) { + e.printStackTrace(); + } + + int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); + + Bitmap newBitmap = rotateBitmap(bitmap, orientation); Canvas canvas = new Canvas(bitmap); canvas.drawARGB(transparent ? 0 : 255, 255, 255, 255); From d07ac31d9f681c074c1de4b6e76d50f687f43559 Mon Sep 17 00:00:00 2001 From: Malik Kawee <> Date: Mon, 27 Apr 2020 16:23:46 +0500 Subject: [PATCH 2/4] Crash on samsung S devices fixed --- .../main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java b/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java index a5108e9b..e34fe7a2 100644 --- a/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java +++ b/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java @@ -440,7 +440,7 @@ private static Bitmap rotateBitmap(Bitmap bitmap, int orientation) { } try { Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); - bitmap.recycle(); + // bitmap.recycle(); return bmRotated; } catch (OutOfMemoryError e) { From 898384cde3eaaf48c813151566e47550110b7a48 Mon Sep 17 00:00:00 2001 From: Malik Kawee <> Date: Tue, 21 Jul 2020 16:08:30 +0500 Subject: [PATCH 3/4] #code cleanup --- .../terrylinla/rnsketchcanvas/SketchCanvas.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java b/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java index e34fe7a2..8f2ed500 100644 --- a/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java +++ b/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java @@ -440,8 +440,6 @@ private static Bitmap rotateBitmap(Bitmap bitmap, int orientation) { } try { Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); - // bitmap.recycle(); - return bmRotated; } catch (OutOfMemoryError e) { e.printStackTrace(); @@ -449,21 +447,6 @@ private static Bitmap rotateBitmap(Bitmap bitmap, int orientation) { } } -// public static void normalizeImageForUri(Context context, Uri uri) { -// try { -// Log.d("normalize", "URI value = " + uri.getPath()); -// ExifInterface exif = new ExifInterface(uri.getPath()); -// Log.d("normalize", "Exif value = " + exif); -// int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); -// Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri); -// Bitmap rotatedBitmap = rotateBitmap(bitmap, orientation); -// if (!bitmap.equals(rotatedBitmap)) { -// saveBitmapToFile(context, rotatedBitmap, uri); -// } -// } catch (IOException e) { -// e.printStackTrace(); -// } -// } private Bitmap createImage(boolean transparent, boolean includeImage, boolean includeText, boolean cropToImageSize) { Bitmap bitmap = Bitmap.createBitmap( From a13a70e273f1f5f070dd83d3ff7389a2b56ffc6c Mon Sep 17 00:00:00 2001 From: Malik Kawee <> Date: Mon, 19 Oct 2020 13:19:12 +0500 Subject: [PATCH 4/4] #added null check for background image --- .../java/com/terrylinla/rnsketchcanvas/SketchCanvas.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java b/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java index 8f2ed500..0068ea35 100644 --- a/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java +++ b/android/src/main/java/com/terrylinla/rnsketchcanvas/SketchCanvas.java @@ -81,8 +81,6 @@ public boolean openImageFile(String filename, String directory, String mode) { BitmapFactory.decodeResource(mContext.getResources(), res); if(bitmap != null) { backgroundURI = Uri.fromFile(file); - - ExifInterface exif = null; try { exif = new ExifInterface(backgroundURI.getPath()); @@ -453,6 +451,9 @@ private Bitmap createImage(boolean transparent, boolean includeImage, boolean in mBackgroundImage != null && cropToImageSize ? mOriginalWidth : getWidth(), mBackgroundImage != null && cropToImageSize ? mOriginalHeight : getHeight(), Bitmap.Config.ARGB_8888); + + // if background is not null, then rotate it + if (backgroundURI != null){ ExifInterface exif = null; try { exif = new ExifInterface(backgroundURI.getPath()); @@ -463,6 +464,7 @@ private Bitmap createImage(boolean transparent, boolean includeImage, boolean in int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); Bitmap newBitmap = rotateBitmap(bitmap, orientation); + } Canvas canvas = new Canvas(bitmap); canvas.drawARGB(transparent ? 0 : 255, 255, 255, 255);