mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-09 13:50:57 +00:00
Use new BitmapHelper to decode Bitmap and downsample image to required size
This commit is contained in:
1 parent
fa4f8d3dcf
commit
21317cef6f
4 files changed
+198
-9
No files matched your search
+187
@@ -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>
|
||||
|
||||
|
||||
+9
-9
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user