From fb5af098b9fe015bd620987bc624f8b287bdd408 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 13 Oct 2016 10:25:45 -0400 Subject: [PATCH 1/4] Resize/crop downloaded featured image --- .../reader/views/ReaderRelatedPostsView.java | 3 ++ .../android/widgets/WPNetworkImageView.java | 33 +++++++++++++++++++ .../main/res/layout/reader_related_post.xml | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/views/ReaderRelatedPostsView.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/views/ReaderRelatedPostsView.java index 8fea7d13c179..eda4b4ddb446 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/views/ReaderRelatedPostsView.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/views/ReaderRelatedPostsView.java @@ -2,6 +2,7 @@ import android.annotation.TargetApi; import android.content.Context; +import android.graphics.Point; import android.os.Build; import android.support.annotation.NonNull; import android.util.AttributeSet; @@ -205,7 +206,9 @@ private void showFeaturedImage(final View postView, final ReaderRelatedPost rela @Override public void onGlobalLayout() { postView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + Point pt = new Point(mFeaturedImageWidth, postView.getHeight()); String photonUrl = PhotonUtils.getPhotonImageUrl(relatedPost.getFeaturedImageUrl(), mFeaturedImageWidth, postView.getHeight()); + imgFeatured.setCropping(pt); imgFeatured.setImageUrl(photonUrl, WPNetworkImageView.ImageType.PHOTO); } }); diff --git a/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java b/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java index 1f858664c534..71116ef0997b 100644 --- a/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java +++ b/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java @@ -5,6 +5,8 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Point; import android.graphics.drawable.ColorDrawable; import android.os.AsyncTask; import android.support.annotation.ColorRes; @@ -59,6 +61,7 @@ public interface ImageLoadListener { private int mDefaultImageResId; private int mErrorImageResId; + private Point mCropping; private static final HashSet mUrlSkipList = new HashSet<>(); @@ -84,6 +87,10 @@ public void setImageUrl(String url, ImageType imageType, ImageLoadListener image loadImageIfNecessary(false, imageLoadListener); } + public void setCropping(Point point) { + mCropping = point; + } + /* * determine whether we can show a thumbnail image for the passed video - currently * we support YouTube, Vimeo & standard images @@ -258,6 +265,11 @@ private void handleResponse(ImageLoader.ImageContainer response, boolean isCache setVisibility(View.VISIBLE); } + // if cropping is requested, do it before further manipulation + if (mCropping != null) { + bitmap = cropBitmap(bitmap, mCropping.x, mCropping.y); + } + // Apply circular rounding to avatars in a background task if (mImageType == ImageType.AVATAR) { new ShapeBitmapTask(ShapeType.CIRCLE, imageLoadListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, bitmap); @@ -278,6 +290,27 @@ private void handleResponse(ImageLoader.ImageContainer response, boolean isCache } } + private static Bitmap cropBitmap(Bitmap bitmap, int newWidth, int newHeight) { + if (bitmap == null) { + return null; + } + if (newWidth <= 0 || newHeight <= 0) { + AppLog.w(AppLog.T.READER, "WPNetworkImageView > invalid cropping size"); + return bitmap; + } + + int bmpWidth = bitmap.getWidth(); + int bmpHeight = bitmap.getHeight(); + + float scaleWidth = ((float) newWidth) / bmpWidth; + float scaleHeight = ((float) newHeight) / bmpHeight; + + Matrix matrix = new Matrix(); + matrix.postScale(scaleWidth, scaleHeight); + + return Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, false); + } + public void invalidateImage() { mUrlSkipList.clear(); diff --git a/WordPress/src/main/res/layout/reader_related_post.xml b/WordPress/src/main/res/layout/reader_related_post.xml index f7b10c662d68..6540b20835a7 100644 --- a/WordPress/src/main/res/layout/reader_related_post.xml +++ b/WordPress/src/main/res/layout/reader_related_post.xml @@ -17,7 +17,7 @@ android:layout_width="@dimen/reader_related_post_image_width" android:layout_height="match_parent" android:layout_marginRight="@dimen/margin_large" - android:scaleType="fitXY" + android:scaleType="centerCrop" android:visibility="gone" tools:src="@drawable/box_with_pages_top" tools:visibility="visible" /> From f05cf71de08b6d69c48a8899488dcc64517ac853 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 13 Oct 2016 10:41:52 -0400 Subject: [PATCH 2/4] Passing cropping when setting download image url --- .../reader/views/ReaderRelatedPostsView.java | 18 ++++++--- .../android/widgets/WPNetworkImageView.java | 38 +++++++++++++------ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/views/ReaderRelatedPostsView.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/views/ReaderRelatedPostsView.java index eda4b4ddb446..78f2981da2c2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/views/ReaderRelatedPostsView.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/views/ReaderRelatedPostsView.java @@ -2,7 +2,6 @@ import android.annotation.TargetApi; import android.content.Context; -import android.graphics.Point; import android.os.Build; import android.support.annotation.NonNull; import android.util.AttributeSet; @@ -201,15 +200,22 @@ private void showFeaturedImage(final View postView, final ReaderRelatedPost rela } // featured image has height set to MATCH_PARENT so wait for parent view's layout to complete - // before loading image so we can set the image height correctly + // before loading image so we can set the image height correctly, then tell the imageView + // to crop the downloaded image to fit the exact width/height of the view postView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { postView.getViewTreeObserver().removeOnGlobalLayoutListener(this); - Point pt = new Point(mFeaturedImageWidth, postView.getHeight()); - String photonUrl = PhotonUtils.getPhotonImageUrl(relatedPost.getFeaturedImageUrl(), mFeaturedImageWidth, postView.getHeight()); - imgFeatured.setCropping(pt); - imgFeatured.setImageUrl(photonUrl, WPNetworkImageView.ImageType.PHOTO); + int cropWidth = mFeaturedImageWidth; + int cropHeight = postView.getHeight(); + String photonUrl = PhotonUtils.getPhotonImageUrl( + relatedPost.getFeaturedImageUrl(), cropWidth, cropHeight); + imgFeatured.setImageUrl( + photonUrl, + WPNetworkImageView.ImageType.PHOTO, + null, + cropWidth, + cropHeight); } }); diff --git a/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java b/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java index 71116ef0997b..713f1f314518 100644 --- a/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java +++ b/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java @@ -6,7 +6,6 @@ import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Matrix; -import android.graphics.Point; import android.graphics.drawable.ColorDrawable; import android.os.AsyncTask; import android.support.annotation.ColorRes; @@ -61,7 +60,9 @@ public interface ImageLoadListener { private int mDefaultImageResId; private int mErrorImageResId; - private Point mCropping; + + private int mCropWidth; + private int mCropHeight; private static final HashSet mUrlSkipList = new HashSet<>(); @@ -80,17 +81,29 @@ public void setImageUrl(String url, ImageType imageType) { } public void setImageUrl(String url, ImageType imageType, ImageLoadListener imageLoadListener) { + setImageUrl(url, imageType, imageLoadListener, 0, 0); + } + + public void setImageUrl(String url, + ImageType imageType, + ImageLoadListener imageLoadListener, + int cropWidth, + int cropHeight) { mUrl = url; mImageType = imageType; + if (cropWidth > 0 && cropHeight > 0) { + mCropWidth = cropWidth; + mCropHeight = cropHeight; + } else { + mCropWidth = 0; + mCropHeight = 0; + } + // The URL has potentially changed. See if we need to load it. loadImageIfNecessary(false, imageLoadListener); } - public void setCropping(Point point) { - mCropping = point; - } - /* * determine whether we can show a thumbnail image for the passed video - currently * we support YouTube, Vimeo & standard images @@ -266,8 +279,8 @@ private void handleResponse(ImageLoader.ImageContainer response, boolean isCache } // if cropping is requested, do it before further manipulation - if (mCropping != null) { - bitmap = cropBitmap(bitmap, mCropping.x, mCropping.y); + if (mCropWidth > 0 && mCropHeight > 0) { + bitmap = cropBitmap(bitmap, mCropWidth, mCropHeight); } // Apply circular rounding to avatars in a background task @@ -290,14 +303,15 @@ private void handleResponse(ImageLoader.ImageContainer response, boolean isCache } } + /* + * crops the passed bitmap to fit the passed width/height - bitmap will be resized if + * necessary to ensure it fills the desired size before cropping + */ private static Bitmap cropBitmap(Bitmap bitmap, int newWidth, int newHeight) { if (bitmap == null) { + AppLog.w(AppLog.T.READER, "WPNetworkImageView > cannot crop a null bitmap"); return null; } - if (newWidth <= 0 || newHeight <= 0) { - AppLog.w(AppLog.T.READER, "WPNetworkImageView > invalid cropping size"); - return bitmap; - } int bmpWidth = bitmap.getWidth(); int bmpHeight = bitmap.getHeight(); From df9ea152dd2fc9dfaede760b6ad78a148aae0d58 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 13 Oct 2016 10:43:52 -0400 Subject: [PATCH 3/4] Prevent possible /0 exception --- .../org/wordpress/android/widgets/WPNetworkImageView.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java b/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java index 713f1f314518..9e8159e06058 100644 --- a/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java +++ b/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java @@ -316,6 +316,11 @@ private static Bitmap cropBitmap(Bitmap bitmap, int newWidth, int newHeight) { int bmpWidth = bitmap.getWidth(); int bmpHeight = bitmap.getHeight(); + if (bmpWidth == 0 || bmpHeight == 0) { + AppLog.w(AppLog.T.READER, "WPNetworkImageView > cannot crop an empty bitmap"); + return null; + } + float scaleWidth = ((float) newWidth) / bmpWidth; float scaleHeight = ((float) newHeight) / bmpHeight; From 89bdf94307ed1af71862cf7a803b205b8ecff0e2 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Wed, 19 Oct 2016 05:37:51 -0400 Subject: [PATCH 4/4] Use ThumbnailUtils.extractThumbnail --- .../android/widgets/WPNetworkImageView.java | 31 ++----------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java b/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java index 9e8159e06058..05f7eaf61d65 100644 --- a/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java +++ b/WordPress/src/main/java/org/wordpress/android/widgets/WPNetworkImageView.java @@ -5,8 +5,8 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; -import android.graphics.Matrix; import android.graphics.drawable.ColorDrawable; +import android.media.ThumbnailUtils; import android.os.AsyncTask; import android.support.annotation.ColorRes; import android.support.annotation.DrawableRes; @@ -280,7 +280,7 @@ private void handleResponse(ImageLoader.ImageContainer response, boolean isCache // if cropping is requested, do it before further manipulation if (mCropWidth > 0 && mCropHeight > 0) { - bitmap = cropBitmap(bitmap, mCropWidth, mCropHeight); + bitmap = ThumbnailUtils.extractThumbnail(bitmap, mCropWidth, mCropHeight); } // Apply circular rounding to avatars in a background task @@ -303,33 +303,6 @@ private void handleResponse(ImageLoader.ImageContainer response, boolean isCache } } - /* - * crops the passed bitmap to fit the passed width/height - bitmap will be resized if - * necessary to ensure it fills the desired size before cropping - */ - private static Bitmap cropBitmap(Bitmap bitmap, int newWidth, int newHeight) { - if (bitmap == null) { - AppLog.w(AppLog.T.READER, "WPNetworkImageView > cannot crop a null bitmap"); - return null; - } - - int bmpWidth = bitmap.getWidth(); - int bmpHeight = bitmap.getHeight(); - - if (bmpWidth == 0 || bmpHeight == 0) { - AppLog.w(AppLog.T.READER, "WPNetworkImageView > cannot crop an empty bitmap"); - return null; - } - - float scaleWidth = ((float) newWidth) / bmpWidth; - float scaleHeight = ((float) newHeight) / bmpHeight; - - Matrix matrix = new Matrix(); - matrix.postScale(scaleWidth, scaleHeight); - - return Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, false); - } - public void invalidateImage() { mUrlSkipList.clear();