package com.quickblox.q_municate.utils.image;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.TypedValue;
import com.quickblox.q_municate.App;
import com.quickblox.q_municate.R;
import com.quickblox.q_municate.utils.MimeType;
import com.quickblox.q_municate.utils.StorageUtil;
import com.quickblox.q_municate_core.utils.ConstsCore;
import com.quickblox.q_municate_core.utils.DateUtilsCore;
import com.quickblox.q_municate_db.utils.ErrorUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ImageUtils {
public static final int GALLERY_REQUEST_CODE = 111;
public static final int CAMERA_REQUEST_CODE = 222;
public static final int IMAGE_REQUEST_CODE = 333;
private static final String TAG = ImageUtils.class.getSimpleName();
private static final String CAMERA_FILE_NAME_PREFIX = "CAMERA_";
private static final String CAMERA_FILE_EXT = ".jpg";
private static final String CAMERA_FILE_NAME = CAMERA_FILE_NAME_PREFIX + DateUtilsCore.getCurrentTime() + CAMERA_FILE_EXT;
private static final int AVATAR_SIZE = 110;
private Activity activity;
public ImageUtils(Activity activity) {
this.activity = activity;
}
public static void startImagePicker(Activity activity) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(MimeType.IMAGE_MIME);
activity.startActivityForResult(
Intent.createChooser(intent, activity.getString(R.string.dlg_choose_image_from)),
GALLERY_REQUEST_CODE);
}
public static void startImagePicker(Fragment fragment) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(MimeType.IMAGE_MIME);
fragment.startActivityForResult(
Intent.createChooser(intent, fragment.getString(R.string.dlg_choose_image_from)),
GALLERY_REQUEST_CODE);
}
public static void startCameraForResult(Activity activity) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(activity.getPackageManager()) == null) {
return;
}
File photoFile = getTemporaryCameraFile();
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
activity.startActivityForResult(intent, CAMERA_REQUEST_CODE);
}
public static void startCameraForResult(Fragment fragment) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(App.getInstance().getPackageManager()) == null) {
return;
}
File photoFile = getTemporaryCameraFile();
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
fragment.startActivityForResult(intent, CAMERA_REQUEST_CODE);
}
public static File getTemporaryCameraFile() {
File storageDir = StorageUtil.getAppExternalDataDirectoryFile();
File file = new File(storageDir, CAMERA_FILE_NAME);
try {
file.createNewFile();
} catch (IOException e) {
ErrorUtils.logError(e);
}
return file;
}
public static File getLastUsedCameraFile() {
File dataDir = StorageUtil.getAppExternalDataDirectoryFile();
File[] files = dataDir.listFiles();
List<File> filteredFiles = new ArrayList<>();
for (File file : files) {
if (file.getName().startsWith(CAMERA_FILE_NAME_PREFIX)) {
filteredFiles.add(file);
}
}
Collections.sort(filteredFiles);
if (!filteredFiles.isEmpty()) {
return filteredFiles.get(filteredFiles.size() - 1);
} else {
return null;
}
}
public static String saveUriToFile(Uri uri) throws Exception {
ParcelFileDescriptor parcelFileDescriptor = App.getInstance().getContentResolver()
.openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
InputStream inputStream = new FileInputStream(fileDescriptor);
BufferedInputStream bis = new BufferedInputStream(inputStream);
File parentDir = StorageUtil.getAppExternalDataDirectoryFile();
String fileName = String.valueOf(System.currentTimeMillis()) + CAMERA_FILE_EXT;
File resultFile = new File(parentDir, fileName);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(resultFile));
byte[] buf = new byte[2048];
int length;
try {
while ((length = bis.read(buf)) > 0) {
bos.write(buf, 0, length);
}
} catch (Exception e) {
throw new IOException("Can\'t save Storage API bitmap to a file!", e);
} finally {
parcelFileDescriptor.close();
bis.close();
bos.close();
}
return resultFile.getAbsolutePath();
}
public static File getCreatedFileFromUri(Uri uri) {
String filePath;
File file = null;
try {
if (uri != null) {
filePath = ImageUtils.saveUriToFile(uri);
file = new File(filePath);
}
} catch (Exception e) {
ErrorUtils.logError(e);
}
return file;
}
private static int getExifInterfaceOrientation(String pathToFile) {
int orientation = ConstsCore.NOT_INITIALIZED_VALUE;
try {
ExifInterface exifInterface = new ExifInterface(pathToFile);
orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ConstsCore.NOT_INITIALIZED_VALUE);
} catch (Exception e) {
ErrorUtils.logError(e);
}
return orientation;
}
public static void checkForRotation(String imagePath) {
Bitmap bitmap = getBitmapFromFile(imagePath);
if (bitmap.getHeight() > bitmap.getWidth()) {
rotateImage(bitmap, 90);
}
}
private static Bitmap rotateImage(Bitmap bitmap, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return rotatedImg;
}
public static Bitmap getBitmapFromFile(String filePath) {
return BitmapFactory.decodeFile(filePath, getBitmapOption());
}
private static BitmapFactory.Options getBitmapOption() {
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
bitmapOptions.inDither = false;
bitmapOptions.inPurgeable = true;
bitmapOptions.inInputShareable = true;
bitmapOptions.inTempStorage = new byte[32 * 1024];
return bitmapOptions;
}
private static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth,
dstHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth,
dstHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
private static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int) (srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, ConstsCore.ZERO_INT_VALUE, srcRectLeft + srcRectWidth,
srcHeight);
} else {
final int srcRectHeight = (int) (srcWidth / dstAspect);
final int scrRectTop = (int) (srcHeight - srcRectHeight) / 2;
return new Rect(ConstsCore.ZERO_INT_VALUE, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
}
} else {
return new Rect(ConstsCore.ZERO_INT_VALUE, ConstsCore.ZERO_INT_VALUE, srcWidth, srcHeight);
}
}
public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float) srcWidth / (float) srcHeight;
final float dstAspect = (float) dstWidth / (float) dstHeight;
if (srcAspect > dstAspect) {
return new Rect(ConstsCore.ZERO_INT_VALUE, ConstsCore.ZERO_INT_VALUE, dstWidth,
(int) (dstWidth / srcAspect));
} else {
return new Rect(ConstsCore.ZERO_INT_VALUE, ConstsCore.ZERO_INT_VALUE,
(int) (dstHeight * srcAspect), dstHeight);
}
} else {
return new Rect(ConstsCore.ZERO_INT_VALUE, ConstsCore.ZERO_INT_VALUE, dstWidth, dstHeight);
}
}
public static Drawable getRoundIconDrawable(Context context, Bitmap avatarBitmap) {
int actionBarHeight = getActionBarHeight(context);
return getRoundIconDrawable(avatarBitmap, actionBarHeight);
}
private static int getActionBarHeight(Context context) {
TypedValue typedValue = new TypedValue();
int actionBarHeight = AVATAR_SIZE;
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) {
actionBarHeight = TypedValue
.complexToDimensionPixelSize(typedValue.data, context.getResources().getDisplayMetrics());
}
int margin = actionBarHeight / 10;
return actionBarHeight - margin;
}
private static Drawable getRoundIconDrawable(Bitmap avatarBitmap, int size) {
// TODO Remove freaking hardcoded values
Resources res = App.getInstance().getResources();
Bitmap scaledBitmap = createScaledBitmap(avatarBitmap, size, size, ScalingLogic.CROP);
// create rounded image avatar
Bitmap output = Bitmap
.createBitmap(scaledBitmap.getWidth(), scaledBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
int color = App.getInstance().getResources().getColor(R.color.gray);
Paint paint = new Paint();
Rect rect = new Rect(0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight());
RectF rectF = new RectF(rect);
float roundPx = 200;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(scaledBitmap, rect, rect, paint);
// draw two bitmaps on Canvas
int width = output.getWidth();
int height = output.getHeight();
Bitmap finalImage = Bitmap.createBitmap(width, height, output.getConfig());
canvas = new Canvas(finalImage);
canvas.drawBitmap(output, 0, 0, null);
return new BitmapDrawable(res, finalImage);
}
private enum ScalingLogic {
CROP, FIT
}
}