Skip to content

Commit

Permalink
fix scaling
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Knop <[email protected]>
  • Loading branch information
Alex Knop committed Feb 10, 2025
1 parent 6117fd2 commit 1ff1a8a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -529,11 +529,7 @@ class PreviewImageFragment : FileFragment(), Injectable {
}

try {
bitmapResult = BitmapUtils.decodeSampledBitmapFromFile(
storagePath,
minWidth,
minHeight
)
bitmapResult = BitmapUtils.retrieveBitmapFromFile(storagePath, minWidth, minHeight);

if (isCancelled) {
return LoadImage(bitmapResult, null, ocFile)
Expand All @@ -543,12 +539,8 @@ class PreviewImageFragment : FileFragment(), Injectable {
mErrorMessageId = R.string.preview_image_error_unknown_format
Log_OC.e(TAG, "File could not be loaded as a bitmap: $storagePath")
break
} else {
if (MimeType.JPEG.equals(ocFile.mimeType, ignoreCase = true)) {
// Rotate image, obeying exif tag.
bitmapResult = BitmapUtils.rotateImage(bitmapResult, storagePath)
}
}

} catch (e: OutOfMemoryError) {
mErrorMessageId = R.string.common_error_out_memory
if (i < maxDownScale - 1) {
Expand Down
87 changes: 87 additions & 0 deletions app/src/main/java/com/owncloud/android/utils/BitmapUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,44 @@ public static Bitmap decodeSampledBitmapFromFile(String srcPath, int reqWidth, i
return BitmapFactory.decodeFile(srcPath, options);
}

/**
* Decodes a bitmap from a file containing it minimizing the memory use. Scales image to screen size.
*
* @param storagePath Absolute path to the file containing the image.
*/
public static Bitmap retrieveBitmapFromFile(String storagePath, int minWidth, int minHeight){
// Get the original dimensions of the bitmap
var bitmapResolution = getImageResolution(storagePath);
var originalWidth = bitmapResolution[0];
var originalHeight = bitmapResolution[1];

// Detect Orientation and swap height/width if the image is to be rotated
var shouldRotate = detectRotateImage(storagePath);
if (shouldRotate) {
// Swap the width and height
var tempWidth = originalWidth;
originalWidth = originalHeight;
originalHeight = tempWidth;
}

var bitmapResult = decodeSampledBitmapFromFile(
storagePath, originalWidth, originalHeight);

// Calculate the scaling factors based on screen dimensions
var widthScaleFactor = (float) minWidth/ bitmapResult.getWidth();
var heightScaleFactor = (float) minHeight / bitmapResult.getHeight();

// Use the smaller scaling factor to maintain aspect ratio
var scaleFactor = Math.min(widthScaleFactor, heightScaleFactor);

// Calculate the new scaled width and height
var scaledWidth = (int) (bitmapResult.getWidth() * scaleFactor);
var scaledHeight = (int) (bitmapResult.getHeight() * scaleFactor);

bitmapResult = scaleBitmap(bitmapResult,scaledWidth,scaledHeight);

return bitmapResult;
}
/**
* Calculates a proper value for options.inSampleSize in order to decode a Bitmap minimizing the memory overload and
* covering a target surface of reqWidth x reqHeight if the original image is big enough.
Expand Down Expand Up @@ -162,6 +199,18 @@ public static Bitmap scaleBitmap(Bitmap bitmap, float px, int width, int height,
return Bitmap.createScaledBitmap(bitmap, w, h, true);
}

/**
* scales a given bitmap depending on the given size parameters.
*
* @param bitmap the bitmap to be scaled
* @param width the width
* @param height the height
* @return the scaled bitmap
*/
public static Bitmap scaleBitmap(Bitmap bitmap, int width, int height) {
return Bitmap.createScaledBitmap(bitmap, width, height, true);
}

/**
* Rotate bitmap according to EXIF orientation. Cf. http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/
*
Expand Down Expand Up @@ -230,6 +279,44 @@ public static Bitmap rotateImage(Bitmap bitmap, String storagePath) {
return resultBitmap;
}

/**
* Detect if Image will be rotated according to EXIF orientation. Cf. http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/
*
* @param storagePath Path to source file of bitmap. Needed for EXIF information.
* @return true if image's orientation determines it will be rotated to where height and width change
*/
public static boolean detectRotateImage(String storagePath) {
try {
ExifInterface exifInterface = new ExifInterface(storagePath);
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);

if (orientation != ExifInterface.ORIENTATION_NORMAL) {
switch (orientation) {
// 5
case ExifInterface.ORIENTATION_TRANSPOSE: {
return true;
}
// 6
case ExifInterface.ORIENTATION_ROTATE_90: {
return true;
}
// 7
case ExifInterface.ORIENTATION_TRANSVERSE: {
return true;
}
// 8
case ExifInterface.ORIENTATION_ROTATE_270: {
return true;
}
}
}
}
catch (Exception exception) {
Log_OC.e("BitmapUtil", "Could not read orientation at: " + storagePath);
}
return false;
}

public static int[] getImageResolution(String srcPath) {
Options options = new Options();
options.inJustDecodeBounds = true;
Expand Down

0 comments on commit 1ff1a8a

Please sign in to comment.