-/* ownCloud Android client application
- * Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ * ownCloud Android client application
+ *
+ * @author David A. Velasco
+ * Copyright (C) 2015 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
*/
package com.owncloud.android.utils;
+import com.owncloud.android.lib.common.utils.Log_OC;
+
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
import android.graphics.BitmapFactory.Options;
+import android.media.ExifInterface;
+import android.net.Uri;
+import android.webkit.MimeTypeMap;
+
+import java.io.File;
/**
* Utility class with methods for decoding Bitmaps.
- *
- * @author David A. Velasco
*/
public class BitmapUtils {
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
-
+
+ // calculates the largest inSampleSize value (for smallest sample) 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;
}
+ /**
+ * Rotate bitmap according to EXIF orientation.
+ * Cf. http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/
+ * @param bitmap Bitmap to be rotated
+ * @param storagePath Path to source file of bitmap. Needed for EXIF information.
+ * @return correctly EXIF-rotated bitmap
+ */
+ public static Bitmap rotateImage(Bitmap bitmap, String storagePath){
+ Bitmap resultBitmap = bitmap;
+
+ try
+ {
+ ExifInterface exifInterface = new ExifInterface(storagePath);
+ int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
+
+ Matrix matrix = new Matrix();
+
+ // 1: nothing to do
+
+ // 2
+ if (orientation == ExifInterface.ORIENTATION_FLIP_HORIZONTAL)
+ {
+ matrix.postScale(-1.0f, 1.0f);
+ }
+ // 3
+ else if (orientation == ExifInterface.ORIENTATION_ROTATE_180)
+ {
+ matrix.postRotate(180);
+ }
+ // 4
+ else if (orientation == ExifInterface.ORIENTATION_FLIP_VERTICAL)
+ {
+ matrix.postScale(1.0f, -1.0f);
+ }
+ // 5
+ else if (orientation == ExifInterface.ORIENTATION_TRANSPOSE)
+ {
+ matrix.postRotate(-90);
+ matrix.postScale(1.0f, -1.0f);
+ }
+ // 6
+ else if (orientation == ExifInterface.ORIENTATION_ROTATE_90)
+ {
+ matrix.postRotate(90);
+ }
+ // 7
+ else if (orientation == ExifInterface.ORIENTATION_TRANSVERSE)
+ {
+ matrix.postRotate(90);
+ matrix.postScale(1.0f, -1.0f);
+ }
+ // 8
+ else if (orientation == ExifInterface.ORIENTATION_ROTATE_270)
+ {
+ matrix.postRotate(270);
+ }
+
+ // Rotate the bitmap
+ resultBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ if (resultBitmap != bitmap) {
+ bitmap.recycle();
+ }
+ }
+ catch (Exception exception)
+ {
+ Log_OC.e("BitmapUtil", "Could not rotate the image: " + storagePath);
+ }
+ return resultBitmap;
+ }
+
+ /**
+ * Converts an HSL color value to RGB. Conversion formula
+ * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
+ * Assumes h, s, and l are contained in the set [0, 1] and
+ * returns r, g, and b in the set [0, 255].
+ * from: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
+ *
+ * @param integer h The hue
+ * @param Integer s The saturation
+ * @param Integer l The lightness
+ * @return Array The RGB representation
+ */
+ public static int[] hslToRgb(Double h, Double s, Double l){
+ Double r, g, b;
+
+ if(s == 0){
+ r = g = b = l; // achromatic
+ } else {
+ Double q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ Double p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1/3) * 255;
+ g = hue2rgb(p, q, h) * 255;
+ b = hue2rgb(p, q, h - 1/3) * 255;
+ }
+
+
+ int[] array = {r.intValue(), g.intValue(), b.intValue()};
+ return array;
+ }
+
+ private static Double hue2rgb(Double p, Double q, Double t){
+ if(t < 0) t += 1;
+ if(t > 1) t -= 1;
+ if(t < 1/6) return p + (q - p) * 6 * t;
+ if(t < 1/2) return q;
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
+ return p;
+ }
+
+
+ /**
+ * Checks if file passed is an image
+ * @param file
+ * @return true/false
+ */
+ public static boolean isImage(File file) {
+ Uri selectedUri = Uri.fromFile(file);
+ String fileExtension = MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString().toLowerCase());
+ String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
+
+ return (mimeType != null && mimeType.startsWith("image/"));
+ }
+
}