Use new BitmapHelper to decode Bitmap and downsample image to required size

This commit is contained in:
Teresa Holfeld committed 2016-04-05 12:18:52 +02:00
1 parent fa4f8d3dcf
commit 21317cef6f
4 files changed
+198 -9

No files matched your search

@@ -0,0 +1,187 @@
package com.sap.sailing.android.shared.util;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.AttrRes;
import android.support.annotation.DrawableRes;
import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.util.TypedValue;
import android.view.View;
/**
* Utility class for decoding Bitmap files and requiring Drawables.
*/
public class BitmapHelper {
/**
* Decodes a bitmap resource, calculates its sample size, and returns the size-reduced Bitmap for that resource.
*
* @param res the resource to decode
* @param resId the resource ID
* @param reqWidth the required width of the output Bitmap
* @param reqHeight the required height of the output Bitmap
* @return the down-sampled decoded Bitmap
*/
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
/**
* Decodes a bitmap file, calculates its sample size, and returns the size-reduced Bitmap for that file.
*
* @param fileName the absolute path of the file to decode
* @param reqWidth the required width of the output Bitmap
* @param reqHeight the required height of the output Bitmap
* @param preferredConfig additional preferred config (optional, can be null)
* @return the down-sampled decoded Bitmap
*/
public static Bitmap decodeSampleBitmapFromFile(String fileName, int reqWidth, int reqHeight,
Bitmap.Config preferredConfig) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
if (preferredConfig != null) {
options.inPreferredConfig = preferredConfig;
}
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(fileName, options);
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
/**
* Gets a Drawable from the provided attribute resource.
*
* @param context the context
* @param attrRes the attribute resource
* @return the Drawable of the resource
*/
// @SuppressWarnings, but it is handled correctly
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static Drawable getAttrDrawable(Context context, @AttrRes int attrRes) {
Drawable drawable = null;
TypedValue value = new TypedValue();
if (context.getTheme().resolveAttribute(attrRes, value, true)) {
String[] data = String.valueOf(value.string).split("/");
int resId = context.getResources().getIdentifier(data[2].substring(0, data[2].length() - 4), "drawable", context.getPackageName());
if (resId != 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
drawable = context.getDrawable(resId);
} else {
drawable = context.getResources().getDrawable(resId);
}
}
}
return drawable;
}
/**
* Gets a Drawable from the provided attribute identifier.
*
* @param context the context
* @param attr the attribute identifier specifying a Drawable resource
* @return the Drawable of the resource
*/
public static Drawable getAttrDrawable(Context context, String attr) {
int attrRes = context.getResources().getIdentifier(attr, "attr", context.getPackageName());
if (attrRes != 0) {
return getAttrDrawable(context, attrRes);
}
return null;
}
/**
* Sets the given Drawable as background for the given View.
*
* @param view the view that gets its background set
* @param drawable the Drawable for the background
*/
// @SuppressWarnings, but it is handled correctly
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void setBackground(View view, Drawable drawable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.setBackground(drawable);
} else {
view.setBackgroundDrawable(drawable);
}
}
/**
* Tints a drawable given by its resource ID in the given color.
*
* @param context the context
* @param drawableResId the resource ID of the drawable to tint
* @param color the color in which the drawable should be tinted
* @return the tinted Drawable
*/
public static Drawable getTintedDrawable(Context context, @DrawableRes int drawableResId, int color) {
Drawable drawable = ContextCompat.getDrawable(context, drawableResId);
drawable = DrawableCompat.wrap(drawable).mutate();
DrawableCompat.setTint(drawable, color);
return drawable;
}
/**
* Creates a Bitmap from the given Drawable. Uses {@link Bitmap.Config#ARGB_8888}.
*
* @param drawable the source Drawable
* @return the Bitmap for that Drawable
*/
public static Bitmap toBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
@@ -171,6 +171,7 @@
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:contentDescription="@string/content_description_flag_icon"
android:adjustViewBounds="true"
android:textColor="@color/white"/>
</RelativeLayout>
@@ -148,6 +148,7 @@
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:contentDescription="@string/content_description_flag_icon"
android:adjustViewBounds="true"
android:textColor="@color/white"/>
</RelativeLayout>
@@ -39,6 +39,7 @@ import com.sap.sailing.android.shared.data.http.HttpGetRequest;
import com.sap.sailing.android.shared.data.http.HttpJsonPostRequest;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.ui.activities.AbstractRegattaActivity;
import com.sap.sailing.android.shared.util.BitmapHelper;
import com.sap.sailing.android.shared.util.NetworkHelper;
import com.sap.sailing.android.shared.util.NetworkHelper.NetworkHelperError;
import com.sap.sailing.android.shared.util.NetworkHelper.NetworkHelperFailureListener;
@@ -52,7 +53,6 @@ import com.sap.sailing.android.tracking.app.upload.UploadResult;
import com.sap.sailing.android.tracking.app.upload.UploadTeamImageTask;
import com.sap.sailing.android.tracking.app.utils.AboutHelper;
import com.sap.sailing.android.tracking.app.utils.AppPreferences;
import com.sap.sailing.android.tracking.app.utils.BitmapHelper;
import com.sap.sailing.android.tracking.app.utils.CheckinManager;
import com.sap.sailing.android.tracking.app.utils.DatabaseHelper;
import com.sap.sailing.android.tracking.app.valueobjects.CheckinData;
@@ -205,7 +205,8 @@ public class RegattaActivity extends AbstractRegattaActivity
getRegattaFragment().setChangePhotoButtonHidden(true);
ImageView imageView = (ImageView) findViewById(R.id.userImage);
Bitmap storedImage = getStoredImage(getLeaderboardImageFileName(leaderboard.name));
String fileName = getLeaderboardImageFileName(leaderboard.name);
Bitmap storedImage = getStoredImage(fileName, imageView.getWidth(), imageView.getHeight());
if (storedImage == null) {
askServerAboutTeamImageUrl(imageView);
} else {
@@ -214,8 +215,8 @@ public class RegattaActivity extends AbstractRegattaActivity
}
ImageView flagImageView = (ImageView) findViewById(R.id.flag_image);
Bitmap storedFlagImage = getStoredImage(getFlagImageFileName(competitor.countryCode.toLowerCase(Locale
.getDefault())));
String flagFileName = getFlagImageFileName(competitor.countryCode.toLowerCase(Locale.getDefault()));
Bitmap storedFlagImage = getStoredImage(flagFileName, flagImageView.getWidth(), flagImageView.getHeight());
if (storedFlagImage == null) {
String urlStr = String.format("%s/gwt/images/flags/%s.png", event.server,
competitor.countryCode.toLowerCase(Locale.getDefault()));
@@ -314,14 +315,13 @@ public class RegattaActivity extends AbstractRegattaActivity
*
* @return
*/
private Bitmap getStoredImage(String fileName) {
private Bitmap getStoredImage(String fileName, int width, int height) {
File pictureFile = getImageFile(fileName);
if (pictureFile == null || !pictureFile.exists()) {
return null;
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return BitmapFactory.decodeFile(pictureFile.getAbsolutePath(), options);
Bitmap.Config preferredConfig = Bitmap.Config.ARGB_8888;
return BitmapHelper.decodeSampleBitmapFromFile(pictureFile.getAbsolutePath(), width, height, preferredConfig);
}
/**
@@ -594,7 +594,7 @@ public class RegattaActivity extends AbstractRegattaActivity
protected void onPostExecute(File result) {
if (result != null && result.exists()) {
bmImage.setImageBitmap(BitmapHelper.getBitmapFromFile(result, bmImage.getMeasuredWidth(), bmImage.getMeasuredHeight()));
bmImage.setImageBitmap(BitmapHelper.decodeSampleBitmapFromFile(result.getPath(), bmImage.getMeasuredWidth(), bmImage.getMeasuredHeight(), null));
userImageUpdated();
} else {
ExLog.e(RegattaActivity.this, TAG, "Failed to download leaderboard image at url " + downloadUrl);