package org.wordpress.android.util;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Video;
import android.util.FloatMath;
import android.widget.ImageView;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class ImageHelper {
public static int[] getImageSize(Uri uri, Context context) {
String path = null;
if (uri.toString().contains("content:")) {
String[] projection;
Uri imgPath;
projection = new String[] { Images.Media._ID, Images.Media.DATA };
imgPath = uri;
Cursor cur = context.getContentResolver().query(imgPath,
projection, null, null, null);
String thumbData = "";
if (cur.moveToFirst()) {
int dataColumn;
dataColumn = cur.getColumnIndex(Images.Media.DATA);
thumbData = cur.getString(dataColumn);
path = thumbData;
}
} else { // file is not in media library
path = uri.toString().replace("file://", "");
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
int[] dimensions = { imageWidth, imageHeight };
return dimensions;
}
public byte[] createThumbnail(byte[] bytes, String sMaxImageWidth,
String orientation, boolean tiny) {
// creates a thumbnail and returns the bytes
int finalHeight = 0;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Bitmap bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opts);
int width = opts.outWidth;
int finalWidth = 500; // default to this if there's a problem
// Change dimensions of thumbnail
if (tiny) {
finalWidth = 150;
}
byte[] finalBytes;
if (sMaxImageWidth.equals("Original Size")) {
finalBytes = bytes;
} else {
finalWidth = Integer.parseInt(sMaxImageWidth);
if (finalWidth > width) {
// don't resize
finalBytes = bytes;
} else {
int sample = 0;
float fWidth = width;
sample = Double.valueOf(FloatMath.ceil(fWidth / 1200))
.intValue();
if (sample == 3) {
sample = 4;
} else if (sample > 4 && sample < 8) {
sample = 8;
}
opts.inSampleSize = sample;
opts.inJustDecodeBounds = false;
try {
bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length,
opts);
} catch (OutOfMemoryError e) {
// out of memory
return null;
}
if (bm == null)
return null;
float percentage = (float) finalWidth / bm.getWidth();
float proportionateHeight = bm.getHeight() * percentage;
finalHeight = (int) Math.rint(proportionateHeight);
float scaleWidth = ((float) finalWidth) / bm.getWidth();
float scaleHeight = ((float) finalHeight) / bm.getHeight();
float scaleBy = Math.min(scaleWidth, scaleHeight);
// Create a matrix for the manipulation
Matrix matrix = new Matrix();
// Resize the bitmap
matrix.postScale(scaleBy, scaleBy);
if ((orientation != null)
&& (orientation.equals("90")
|| orientation.equals("180") || orientation
.equals("270"))) {
matrix.postRotate(Integer.valueOf(orientation));
}
Bitmap resized;
try {
resized = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), matrix, true);
} catch (OutOfMemoryError e) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
resized.compress(Bitmap.CompressFormat.JPEG, 85, baos);
bm.recycle(); // free up memory
resized.recycle();
finalBytes = baos.toByteArray();
}
}
return finalBytes;
}
public String getExifOrientation(String path, String orientation) {
ExifInterface exif;
try {
exif = new ExifInterface(path);
} catch (IOException e) {
return orientation;
}
String exifOrientation = exif
.getAttribute(ExifInterface.TAG_ORIENTATION);
if (exifOrientation != null) {
if (exifOrientation.equals("1")) {
orientation = "0";
} else if (exifOrientation.equals("3")) {
orientation = "180";
} else if (exifOrientation.equals("6")) {
orientation = "90";
} else if (exifOrientation.equals("8")) {
orientation = "270";
}
} else {
orientation = "0";
}
return orientation;
}
// borrowed from
// http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
return downloadBitmap(params[0]);
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null && bitmap != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
public static Bitmap downloadBitmap(String url) {
final DefaultHttpClient client = new DefaultHttpClient();
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
// Log.w("ImageDownloader", "Error " + statusCode +
// " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e) {
// Could provide a more explicit error message for IOException or
// IllegalStateException
getRequest.abort();
// Log.w("ImageDownloader", "Error while retrieving bitmap from " +
// url);
}
return null;
}
public Map<String, Object> getImageBytesForPath(String filePath, Context ctx) {
Uri curStream = null;
String[] projection;
Map<String, Object> mediaData = new HashMap<String, Object>();
String title = "", orientation = "";
byte[] bytes;
if (filePath != null) {
if (!filePath.contains("content://"))
curStream = Uri.parse("content://media" + filePath);
else
curStream = Uri.parse(filePath);
}
if (curStream != null) {
if (filePath.contains("video")) {
int videoID = Integer.parseInt(curStream.getLastPathSegment());
projection = new String[] { Video.Thumbnails._ID,
Video.Thumbnails.DATA };
ContentResolver crThumb = ctx.getContentResolver();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
Bitmap videoBitmap = MediaStore.Video.Thumbnails.getThumbnail(
crThumb, videoID,
MediaStore.Video.Thumbnails.MINI_KIND, options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
videoBitmap
.compress(Bitmap.CompressFormat.PNG, 100, stream);
bytes = stream.toByteArray();
title = "Video";
videoBitmap = null;
} catch (Exception e) {
return null;
}
} else {
projection = new String[] { Images.Thumbnails._ID,
Images.Thumbnails.DATA, Images.Media.ORIENTATION };
String path = "";
Cursor cur;
try {
cur = ctx.getContentResolver().query(curStream, projection,
null, null, null);
} catch (Exception e1) {
return null;
}
File jpeg = null;
if (cur != null) {
String thumbData = "";
if (cur.moveToFirst()) {
int dataColumn, orientationColumn;
dataColumn = cur.getColumnIndex(Images.Media.DATA);
thumbData = cur.getString(dataColumn);
orientationColumn = cur
.getColumnIndex(Images.Media.ORIENTATION);
orientation = cur.getString(orientationColumn);
if (orientation == null)
orientation = "";
}
if (thumbData == null) {
return null;
}
jpeg = new File(thumbData);
path = thumbData;
} else {
path = filePath.toString().replace("file://", "");
jpeg = new File(path);
}
title = jpeg.getName();
try {
bytes = new byte[(int) jpeg.length()];
} catch (Exception e) {
return null;
} catch (OutOfMemoryError e) {
return null;
}
DataInputStream in = null;
try {
in = new DataInputStream(new FileInputStream(jpeg));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
try {
in.readFully(bytes);
in.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
title = jpeg.getName();
if (orientation == "") {
orientation = getExifOrientation(path, orientation);
}
}
mediaData.put("bytes", bytes);
mediaData.put("title", title);
mediaData.put("orientation", orientation);
return mediaData;
} else {
return null;
}
}
}