diff options
| -rw-r--r-- | main/src/cgeo/geocaching/ImageSelectActivity.java | 7 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/ImageUtils.java | 71 |
2 files changed, 54 insertions, 24 deletions
diff --git a/main/src/cgeo/geocaching/ImageSelectActivity.java b/main/src/cgeo/geocaching/ImageSelectActivity.java index 790741f..556aa74 100644 --- a/main/src/cgeo/geocaching/ImageSelectActivity.java +++ b/main/src/cgeo/geocaching/ImageSelectActivity.java @@ -15,7 +15,6 @@ import org.eclipse.jdt.annotation.Nullable; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; @@ -285,9 +284,9 @@ public class ImageSelectActivity extends AbstractActivity { return; } - BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); - bitmapOptions.inSampleSize = 8; - final Bitmap bitmap = BitmapFactory.decodeFile(imageUri.getPath(), bitmapOptions); + final Bitmap bitmap = ImageUtils.readAndScaleImageToFitDisplay(imageUri.getPath()); + int heigth = bitmap.getHeight(); + int width = bitmap.getWidth(); imagePreview.setImageBitmap(bitmap); imagePreview.setVisibility(View.VISIBLE); } diff --git a/main/src/cgeo/geocaching/utils/ImageUtils.java b/main/src/cgeo/geocaching/utils/ImageUtils.java index ea4498b..5ac6c60 100644 --- a/main/src/cgeo/geocaching/utils/ImageUtils.java +++ b/main/src/cgeo/geocaching/utils/ImageUtils.java @@ -28,13 +28,13 @@ public final class ImageUtils { } /** - * Scales a bitmap to the given bounds + * Scales a bitmap to the device display size. * * @param image - * The bitmap to scale + * The image Bitmap representation to scale * @return BitmapDrawable The scaled image */ - public static BitmapDrawable scaleBitmapToFitDisplay(final Bitmap image) { + public static BitmapDrawable scaleBitmapToFitDisplay(@NonNull final Bitmap image) { Point displaySize = Compatibility.getDisplaySize(); final int maxWidth = displaySize.x - 25; final int maxHeight = displaySize.y - 25; @@ -42,13 +42,29 @@ public final class ImageUtils { } /** + * Reads and scales an image file to the device display size. + * + * @param filename + * The image file to read and scale + * @return Bitmap The scaled image + */ + public static Bitmap readAndScaleImageToFitDisplay(@NonNull final String filename) { + Point displaySize = Compatibility.getDisplaySize(); + final int maxWidth = displaySize.x - 25; + final int maxHeight = displaySize.y - 25; + final Bitmap image = readDownsampledImage(filename, maxWidth, maxHeight); + final BitmapDrawable scaledImage = scaleBitmapTo(image, maxWidth, maxHeight); + return scaledImage.getBitmap(); + } + + /** * Scales a bitmap to the given bounds if it is larger, otherwise returns the original bitmap. * * @param image * The bitmap to scale * @return BitmapDrawable The scaled image */ - public static BitmapDrawable scaleBitmapTo(final Bitmap image, final int maxWidth, final int maxHeight) { + public static BitmapDrawable scaleBitmapTo(@NonNull final Bitmap image, final int maxWidth, final int maxHeight) { final CgeoApplication app = CgeoApplication.getInstance(); Bitmap result = image; int width = image.getWidth(); @@ -78,7 +94,7 @@ public final class ImageUtils { * @param pathOfOutputImage * Path to store to */ - public static void storeBitmap(final Bitmap bitmap, final Bitmap.CompressFormat format, final int quality, final String pathOfOutputImage) { + public static void storeBitmap(@NonNull final Bitmap bitmap, @NonNull final Bitmap.CompressFormat format, final int quality, @NonNull final String pathOfOutputImage) { try { FileOutputStream out = new FileOutputStream(pathOfOutputImage); BufferedOutputStream bos = new BufferedOutputStream(out); @@ -104,10 +120,36 @@ public final class ImageUtils { if (maxXY <= 0) { return filePath; } + Bitmap image = readDownsampledImage(filePath, maxXY, maxXY); + final BitmapDrawable scaledImage = scaleBitmapTo(image, maxXY, maxXY); + final File tempImageFile = ImageUtils.getOutputImageFile(); + if (tempImageFile == null) { + Log.e("ImageUtils.readScaleAndWriteImage: unable to write scaled image"); + return null; + } + final String uploadFilename = tempImageFile.getPath(); + storeBitmap(scaledImage.getBitmap(), Bitmap.CompressFormat.JPEG, 75, uploadFilename); + return uploadFilename; + } + + /** + * Reads and scales an image file with downsampling in one step to prevent memory consumption. + * + * @param filePath + * The file to read + * @param maxX + * The desired width + * @param maxY + * The desired height + * @return Bitmap the image or null if file can't be read + */ + @Nullable + public static Bitmap readDownsampledImage(@NonNull final String filePath, final int maxX, final int maxY) { BitmapFactory.Options sizeOnlyOptions = new BitmapFactory.Options(); sizeOnlyOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, sizeOnlyOptions); final int myMaxXY = Math.max(sizeOnlyOptions.outHeight, sizeOnlyOptions.outWidth); + final int maxXY = Math.max(maxX, maxY); final int sampleSize = myMaxXY / maxXY; Bitmap image; if (sampleSize > 1) { @@ -117,18 +159,7 @@ public final class ImageUtils { } else { image = BitmapFactory.decodeFile(filePath); } - if (image == null) { - return null; - } - final BitmapDrawable scaledImage = scaleBitmapTo(image, maxXY, maxXY); - final File tempImageFile = ImageUtils.getOutputImageFile(); - if (tempImageFile == null) { - Log.e("ImageUtils.readScaleAndWriteImage: unable to write scaled image"); - return null; - } - final String uploadFilename = tempImageFile.getPath(); - storeBitmap(scaledImage.getBitmap(), Bitmap.CompressFormat.JPEG, 75, uploadFilename); - return uploadFilename; + return image; } /** Create a File for saving an image or video @@ -140,11 +171,11 @@ public final class ImageUtils { public static File getOutputImageFile() { // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. - + File mediaStorageDir = new File(Compatibility.getExternalPictureDir(), "cgeo"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. - + // Create the storage directory if it does not exist if (!mediaStorageDir.exists()) { if (!FileUtils.mkdirs(mediaStorageDir)) { @@ -152,7 +183,7 @@ public final class ImageUtils { return null; } } - + // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); return new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); |
