From 27eb008fc4cd9db6475dbc10292b3df6cd1a988e Mon Sep 17 00:00:00 2001 From: Jay Wang Date: Sat, 31 Oct 2015 01:10:51 -0700 Subject: Gallery: fix DDM rotation issue in gallery Fix issues in gallery when handling rotation metadata in exif. For those images, pass DDM original captured image data as it needs to match up with aux image. Then re-orient the resulting image in correct orientation according to meta data. Change-Id: Ib8a12f009f0cee7cdbc93878d70af8a6ca93f984 --- .../filters/ImageFilterDualCamFusion.java | 42 ++++++++++--- .../filters/ImageFilterDualCamSketch.java | 39 +++++++++--- .../filtershow/filters/ImageFilterDualCamera.java | 38 ++++++++--- .../filtershow/imageshow/GeometryMathUtils.java | 73 +++++++++++++++++++--- 4 files changed, 153 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamFusion.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamFusion.java index 690add018..3390898c8 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamFusion.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamFusion.java @@ -36,14 +36,16 @@ import android.graphics.Paint; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.Rect; +import android.graphics.RectF; import android.util.Log; import android.widget.Toast; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.cache.BitmapCache; +import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils; -import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder; +import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.pipeline.FilterEnvironment; import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.filtershow.tools.DualCameraNativeEngine; @@ -82,23 +84,35 @@ public class ImageFilterDualCamFusion extends ImageFilter { if(!point.equals(-1,-1)) { Bitmap filteredBitmap = null; + boolean result = false; + int orientation = MasterImage.getImage().getOrientation(); + Rect originalBounds = MasterImage.getImage().getOriginalBounds(); int filteredW; int filteredH; if(quality == FilterEnvironment.QUALITY_FINAL) { - Rect originalBounds = MasterImage.getImage().getOriginalBounds(); filteredW = originalBounds.width(); filteredH = originalBounds.height(); } else { Bitmap originalBmp = MasterImage.getImage().getOriginalBitmapHighres(); filteredW = originalBmp.getWidth(); filteredH = originalBmp.getHeight(); + + // image is rotated + if (orientation == ImageLoader.ORI_ROTATE_90 || + orientation == ImageLoader.ORI_ROTATE_270 || + orientation == ImageLoader.ORI_TRANSPOSE || + orientation == ImageLoader.ORI_TRANSVERSE) { + int tmp = filteredW; + filteredW = filteredH; + filteredH = tmp; + } } filteredBitmap = MasterImage.getImage().getBitmapCache().getBitmap(filteredW, filteredH, BitmapCache.FILTERS); filteredBitmap.setHasAlpha(true); - boolean result = DualCameraNativeEngine.getInstance().getForegroundImg(point.x, point.y, + result = DualCameraNativeEngine.getInstance().getForegroundImg(point.x, point.y, quality != FilterEnvironment.QUALITY_FINAL, filteredBitmap); if(result == false) { @@ -116,8 +130,8 @@ public class ImageFilterDualCamFusion extends ImageFilter { } else { mPaint.reset(); + mPaint.setAntiAlias(true); if(quality == FilterEnvironment.QUALITY_FINAL) { - mPaint.setAntiAlias(true); mPaint.setFilterBitmap(true); mPaint.setDither(true); } @@ -128,16 +142,24 @@ public class ImageFilterDualCamFusion extends ImageFilter { ImagePreset preset = getEnvironment().getImagePreset(); int bmWidth = bitmap.getWidth(); int bmHeight = bitmap.getHeight(); - - canvas.drawColor(0, PorterDuff.Mode.CLEAR); + GeometryHolder holder; if(preset.getDoApplyGeometry()) { - GeometryHolder holder = GeometryMathUtils.unpackGeometry(preset.getGeometryFilters()); - GeometryMathUtils.drawTransformedCropped(holder, canvas, filteredBitmap, bmWidth, bmHeight); + holder = GeometryMathUtils.unpackGeometry(preset.getGeometryFilters()); } else { - canvas.drawBitmap(filteredBitmap, null, - new Rect(0, 0,bmWidth, bmHeight), mPaint); + holder = new GeometryHolder(); } + RectF crop = new RectF(); + Matrix m = GeometryMathUtils.getOriginalToScreen(holder, crop, true, + filteredW, filteredH, bmWidth, bmHeight); + + canvas.drawColor(0, PorterDuff.Mode.CLEAR); + + canvas.save(); + canvas.clipRect(crop); + canvas.drawBitmap(filteredBitmap, m, mPaint); + canvas.restore(); + MasterImage.getImage().getBitmapCache().cache(filteredBitmap); } } diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamSketch.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamSketch.java index 25faefc34..d9ae16967 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamSketch.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamSketch.java @@ -35,14 +35,16 @@ import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.RectF; import android.util.Log; import android.widget.Toast; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.cache.BitmapCache; +import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils; -import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder; +import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.pipeline.FilterEnvironment; import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.filtershow.tools.DualCameraNativeEngine; @@ -77,21 +79,31 @@ public class ImageFilterDualCamSketch extends ImageFilter { if(!point.equals(-1,-1)) { Bitmap filteredBitmap = null; boolean result = false; + int orientation = MasterImage.getImage().getOrientation(); + Rect originalBounds = MasterImage.getImage().getOriginalBounds(); int filteredW; int filteredH; if(quality == FilterEnvironment.QUALITY_FINAL) { - Rect originalBounds = MasterImage.getImage().getOriginalBounds(); filteredW = originalBounds.width(); filteredH = originalBounds.height(); } else { Bitmap originalBmp = MasterImage.getImage().getOriginalBitmapHighres(); filteredW = originalBmp.getWidth(); filteredH = originalBmp.getHeight(); + + // image is rotated + if (orientation == ImageLoader.ORI_ROTATE_90 || + orientation == ImageLoader.ORI_ROTATE_270 || + orientation == ImageLoader.ORI_TRANSPOSE || + orientation == ImageLoader.ORI_TRANSVERSE) { + int tmp = filteredW; + filteredW = filteredH; + filteredH = tmp; + } } filteredBitmap = MasterImage.getImage().getBitmapCache().getBitmap(filteredW, filteredH, BitmapCache.FILTERS); - result = DualCameraNativeEngine.getInstance().applySketch(point.x, point.y, quality != FilterEnvironment.QUALITY_FINAL, filteredBitmap); @@ -109,9 +121,9 @@ public class ImageFilterDualCamSketch extends ImageFilter { return bitmap; } else { + mPaint.reset(); + mPaint.setAntiAlias(true); if(quality == FilterEnvironment.QUALITY_FINAL) { - mPaint.reset(); - mPaint.setAntiAlias(true); mPaint.setFilterBitmap(true); mPaint.setDither(true); } @@ -120,15 +132,22 @@ public class ImageFilterDualCamSketch extends ImageFilter { ImagePreset preset = getEnvironment().getImagePreset(); int bmWidth = bitmap.getWidth(); int bmHeight = bitmap.getHeight(); - + GeometryHolder holder; if(preset.getDoApplyGeometry()) { - GeometryHolder holder = GeometryMathUtils.unpackGeometry(preset.getGeometryFilters()); - GeometryMathUtils.drawTransformedCropped(holder, canvas, filteredBitmap, bmWidth, bmHeight); + holder = GeometryMathUtils.unpackGeometry(preset.getGeometryFilters()); } else { - canvas.drawBitmap(filteredBitmap, null, - new Rect(0, 0,bmWidth, bmHeight), mPaint); + holder = new GeometryHolder(); } + RectF crop = new RectF(); + Matrix m = GeometryMathUtils.getOriginalToScreen(holder, crop, true, + filteredW, filteredH, bmWidth, bmHeight); + + canvas.save(); + canvas.clipRect(crop); + canvas.drawBitmap(filteredBitmap, m, mPaint); + canvas.restore(); + MasterImage.getImage().getBitmapCache().cache(filteredBitmap); } } diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamera.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamera.java index 0082ec388..c8206d511 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamera.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterDualCamera.java @@ -35,14 +35,16 @@ import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.RectF; import android.util.Log; import android.widget.Toast; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.cache.BitmapCache; +import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils; -import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder; +import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.pipeline.FilterEnvironment; import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.filtershow.tools.DualCameraNativeEngine; @@ -81,17 +83,28 @@ public class ImageFilterDualCamera extends ImageFilter { float intensity = (float)value / (float)maxValue; Bitmap filteredBitmap = null; boolean result = false; + int orientation = MasterImage.getImage().getOrientation(); + Rect originalBounds = MasterImage.getImage().getOriginalBounds(); int filteredW; int filteredH; if(quality == FilterEnvironment.QUALITY_FINAL) { - Rect originalBounds = MasterImage.getImage().getOriginalBounds(); filteredW = originalBounds.width(); filteredH = originalBounds.height(); } else { Bitmap originalBmp = MasterImage.getImage().getOriginalBitmapHighres(); filteredW = originalBmp.getWidth(); filteredH = originalBmp.getHeight(); + + // image is rotated + if (orientation == ImageLoader.ORI_ROTATE_90 || + orientation == ImageLoader.ORI_ROTATE_270 || + orientation == ImageLoader.ORI_TRANSPOSE || + orientation == ImageLoader.ORI_TRANSVERSE) { + int tmp = filteredW; + filteredW = filteredH; + filteredH = tmp; + } } filteredBitmap = MasterImage.getImage().getBitmapCache().getBitmap(filteredW, filteredH, BitmapCache.FILTERS); @@ -122,9 +135,9 @@ public class ImageFilterDualCamera extends ImageFilter { return bitmap; } else { + mPaint.reset(); + mPaint.setAntiAlias(true); if(quality == FilterEnvironment.QUALITY_FINAL) { - mPaint.reset(); - mPaint.setAntiAlias(true); mPaint.setFilterBitmap(true); mPaint.setDither(true); } @@ -133,15 +146,22 @@ public class ImageFilterDualCamera extends ImageFilter { ImagePreset preset = getEnvironment().getImagePreset(); int bmWidth = bitmap.getWidth(); int bmHeight = bitmap.getHeight(); - + GeometryHolder holder; if(preset.getDoApplyGeometry()) { - GeometryHolder holder = GeometryMathUtils.unpackGeometry(preset.getGeometryFilters()); - GeometryMathUtils.drawTransformedCropped(holder, canvas, filteredBitmap, bmWidth, bmHeight); + holder = GeometryMathUtils.unpackGeometry(preset.getGeometryFilters()); } else { - canvas.drawBitmap(filteredBitmap, null, - new Rect(0, 0,bmWidth, bmHeight), mPaint); + holder = new GeometryHolder(); } + RectF crop = new RectF(); + Matrix m = GeometryMathUtils.getOriginalToScreen(holder, crop, true, + filteredW, filteredH, bmWidth, bmHeight); + + canvas.save(); + canvas.clipRect(crop); + canvas.drawBitmap(filteredBitmap, m, mPaint); + canvas.restore(); + MasterImage.getImage().getBitmapCache().cache(filteredBitmap); } } diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java index 958170c78..f236675df 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java +++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java @@ -370,16 +370,41 @@ public final class GeometryMathUtils { } public static Matrix getOriginalToScreen(GeometryHolder holder, boolean rotate, - float originalWidth, - float originalHeight, float viewWidth, float viewHeight) { + float originalWidth, float originalHeight, float viewWidth, float viewHeight) { + return getOriginalToScreen(holder, null, rotate, originalWidth, originalHeight, viewWidth, viewHeight); + } + + public static Matrix getOriginalToScreen(GeometryHolder holder, RectF outCrop, + boolean rotate, float originalWidth, float originalHeight, + float viewWidth, float viewHeight) { + RectF crop = new RectF(); + Matrix m; int orientation = MasterImage.getImage().getZoomOrientation(); - int rotation = getRotationForOrientation(orientation); - Rotation prev = holder.rotation; - rotation = (rotation + prev.value()) % 360; - holder.rotation = Rotation.fromValue(rotation); - Matrix m = getCropSelectionToScreenMatrix(null, holder, (int) originalWidth, - (int) originalHeight, (int) viewWidth, (int) viewHeight); - holder.rotation = prev; + + if (orientation == ImageLoader.ORI_ROTATE_90 || + orientation == ImageLoader.ORI_ROTATE_270 || + orientation == ImageLoader.ORI_TRANSPOSE || + orientation == ImageLoader.ORI_TRANSVERSE) { + + crop = getTrueCropRect(holder, (int)originalHeight, (int)originalWidth); + } else { + crop = getTrueCropRect(holder, (int)originalWidth, (int)originalHeight); + } + + float scale = scale(crop.width(), crop.height(), viewWidth, viewHeight); + + m = getFullGeometryMatrix(holder, (int)originalWidth, (int)originalHeight); + if(orientation != ImageLoader.ORI_NORMAL) { + addOrientationToMatrix(m, (int)originalWidth, (int)originalHeight, orientation); + } + + m.postScale(scale, scale); + GeometryMathUtils.scaleRect(crop, scale); + m.postTranslate(viewWidth / 2f - crop.centerX(), viewHeight / 2f - crop.centerY()); + crop.offset(viewWidth / 2f - crop.centerX(), viewHeight / 2f - crop.centerY()); + if(outCrop != null) { + outCrop.set(crop); + } return m; } @@ -426,7 +451,7 @@ public final class GeometryMathUtils { } // Gives matrix for rotated, straightened, mirrored bitmap centered at 0,0. - private static Matrix getFullGeometryMatrix(GeometryHolder holder, int bitmapWidth, + public static Matrix getFullGeometryMatrix(GeometryHolder holder, int bitmapWidth, int bitmapHeight) { float centerX = bitmapWidth / 2f; float centerY = bitmapHeight / 2f; @@ -490,4 +515,32 @@ public final class GeometryMathUtils { return getCropSelectionToScreenMatrix(outCrop, holder, bitmapWidth, bitmapHeight, viewWidth, viewHeight); } + + public static void addOrientationToMatrix(Matrix matrix, int w, int h, int orientation) { + switch (orientation) { + case ImageLoader.ORI_ROTATE_90: + matrix.preRotate(90, w/2, h/2); + break; + case ImageLoader.ORI_ROTATE_180: + matrix.preRotate(180, w/2, h/2); + break; + case ImageLoader.ORI_ROTATE_270: + matrix.preRotate(270, w/2, h/2); + break; + case ImageLoader.ORI_FLIP_HOR: + matrix.preScale(-1, 1); + break; + case ImageLoader.ORI_FLIP_VERT: + matrix.preScale(1, -1); + break; + case ImageLoader.ORI_TRANSPOSE: + matrix.preScale(1, -1); + matrix.preRotate(90, w / 2f, h / 2f); + break; + case ImageLoader.ORI_TRANSVERSE: + matrix.preScale(1, -1); + matrix.preRotate(270, w / 2f, h / 2f); + break; + } + } } -- cgit v1.2.3