package com.rapidftr.utils;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
import com.rapidftr.R;
import com.rapidftr.RapidFtrApplication;
import lombok.Cleanup;
import java.io.*;
import java.security.GeneralSecurityException;
import java.util.Calendar;
import static android.graphics.BitmapFactory.decodeResource;
import static com.rapidftr.utils.EncryptionUtil.getCipherInputStream;
import static com.rapidftr.utils.EncryptionUtil.getCipherOutputStream;
public class PhotoCaptureHelper extends CaptureHelper {
public static final int THUMBNAIL_WIDTH = 96;
public static final int THUMBNAIL_HEIGHT = 96;
public static final int JPEG_QUALITY = 85;
public static final int PHOTO_WIDTH = 475;
public static final int PHOTO_HEIGHT = 635;
public static final int QUALITY = 85;
private Bitmap defaultThumbNail;
public PhotoCaptureHelper(RapidFtrApplication context) {
super(context);
}
public File getTempCaptureFile() {
return new File(getDir(), "temp.jpg");
}
public Calendar getCaptureTime() {
Calendar calendar = Calendar.getInstance();
long time = application.getSharedPreferences().getLong("capture_start_time", System.currentTimeMillis());
calendar.setTimeInMillis(time);
return calendar;
}
public void setCaptureTime() {
application.getSharedPreferences().edit().putLong("capture_start_time", Calendar.getInstance().getTimeInMillis()).commit();
}
public Bitmap getCapture() throws IOException {
return BitmapFactory.decodeFile(getTempCaptureFile().getAbsolutePath());
}
public void deleteCaptures() {
this.deleteTempCapture();
this.deleteGalleryCaptures();
}
protected void deleteTempCapture() {
File file = getTempCaptureFile();
if (file.exists())
file.delete();
}
protected void deleteGalleryCaptures() {
Calendar from = getCaptureTime();
Calendar capturedDate = Calendar.getInstance();
ContentResolver resolver = application.getContentResolver();
@Cleanup Cursor cursor = resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{BaseColumns._ID, MediaStore.Images.ImageColumns.DATE_TAKEN, MediaStore.Images.ImageColumns.DATA},
null, null, null);
while (cursor != null && cursor.moveToNext()) {
try {
capturedDate.setTimeInMillis(cursor.getLong(1));
if (capturedDate.after(from)) {
deleteGalleryCapture(cursor.getString(0), cursor.getString(2));
}
} catch (Exception e) {
Toast.makeText(RapidFtrApplication.getApplicationInstance(), R.string.photo_gallery_delete_error, Toast.LENGTH_LONG).show();
}
}
}
protected void deleteGalleryCapture(String id, String completeFileName) {
File image = new File(completeFileName);
if (image.exists())
image.delete();
application.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, BaseColumns._ID + "=" + id, null);
}
public Bitmap getDefaultThumbnail() {
if(defaultThumbNail == null || defaultThumbNail.getByteCount() == 0){
defaultThumbNail = decodeResource(application.getResources(), R.drawable.no_photo_clip);
}
return defaultThumbNail;
}
public void savePhoto(Bitmap original, int rotationDegree, String fileNameWithoutExtension) throws IOException, GeneralSecurityException {
Bitmap scaled = scaleImageTo(original, PHOTO_WIDTH, PHOTO_HEIGHT);
Bitmap rotated = rotateBitmap(scaled, rotationDegree);
save(rotated, fileNameWithoutExtension, QUALITY, application.getCurrentUser().getDbKey());
scaled.recycle();
rotated.recycle();
}
protected Bitmap resizeImageTo(Bitmap image, int width, int height) {
return Bitmap.createScaledBitmap(image, width, height, false);
}
protected Bitmap scaleImageTo(Bitmap image, int maxWidth, int maxHeight) {
double givenWidth = image.getWidth(), givenHeight = image.getHeight();
double scaleRatio = 1.0;
if (givenWidth > maxWidth || givenHeight > maxHeight) {
if (givenWidth > givenHeight) {
scaleRatio = maxWidth / givenWidth;
} else {
scaleRatio = maxHeight / givenHeight;
}
}
return resizeImageTo(image, (int) (givenWidth * scaleRatio), (int) (givenHeight * scaleRatio));
}
protected void save(Bitmap bitmap, String fileNameWithoutExtension, int quality, String key) throws IOException, GeneralSecurityException {
fileNameWithoutExtension = fileNameWithoutExtension.contains(".jpg")? fileNameWithoutExtension : fileNameWithoutExtension + ".jpg";
File file = new File(getDir(), fileNameWithoutExtension);
if (!file.exists())
file.createNewFile();
@Cleanup OutputStream outputStream = getCipherOutputStream(file, key);
saveImage(bitmap, outputStream, quality);
}
private void saveImage(Bitmap bitmap, OutputStream outputStream, int quality) {
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
}
public void saveThumbnail(Bitmap original, int rotationDegree, String fileNameWithoutExtension) throws IOException, GeneralSecurityException {
Bitmap scaled = resizeImageTo(original, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
Bitmap rotated = rotateBitmap(scaled, rotationDegree);
save(rotated, fileNameWithoutExtension + "_thumb", QUALITY, application.getCurrentUser().getDbKey());
}
public Bitmap loadThumbnail(String fileNameWithoutExtension) throws IOException, GeneralSecurityException {
return loadPhoto(fileNameWithoutExtension + "_thumb");
}
public Bitmap loadPhoto(String fileNameWithoutExtension) throws IOException, GeneralSecurityException {
@Cleanup InputStream inputStream = getDecodedImageStream(fileNameWithoutExtension);
return decodeStreamToBitMap(inputStream);
}
public InputStream getDecodedImageStream(String fileNameWithoutExtension) throws GeneralSecurityException, IOException {
return decodeImage(fileNameWithoutExtension, application.getCurrentUser().getDbKey());
}
private InputStream decodeImage(String fileNameWithoutExtension, String password) throws GeneralSecurityException, IOException {
File file = getFile(fileNameWithoutExtension, ".jpg");
return getCipherInputStream(file, password);
}
public Bitmap getThumbnailOrDefault(String fileNameWithoutExtension) {
try {
getFile(fileNameWithoutExtension, ".jpg");
return loadThumbnail(fileNameWithoutExtension);
} catch (FileNotFoundException e) {
return getDefaultThumbnail();
} catch (Exception e) {
Log.e("Image", "Error while getting the Thumbnail", e);
throw new RuntimeException(e);
}
}
public int getPictureRotation() throws IOException {
ExifInterface exif = getExifInterface();
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return 90;
case ExifInterface.ORIENTATION_ROTATE_180:
return 180;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270;
default:
return 0;
}
}
protected ExifInterface getExifInterface() throws IOException {
return new ExifInterface(getTempCaptureFile().getAbsolutePath());
}
protected Bitmap rotateBitmap(Bitmap bitmap, int rotationDegree) throws IOException {
Matrix matrix = new Matrix();
matrix.postRotate(rotationDegree);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
public void convertPhoto(String photo, String existingKey, String newKey) {
try {
@Cleanup InputStream inputStreamPhoto = decodeImage(photo, existingKey);
Bitmap bitmap = decodeStreamToBitMap(inputStreamPhoto);
@Cleanup InputStream inputStreamThumb = decodeImage(photo + "_thumb", existingKey);
Bitmap bitmap_thumbnail = decodeStreamToBitMap(inputStreamThumb);
save(bitmap, photo, QUALITY, newKey);
save(bitmap_thumbnail, photo + "_thumb", QUALITY, newKey);
} catch (IOException e) {
Log.e("ERROR WHILE CONVERTING PHOTO", e.getMessage());
new RuntimeException(e.getMessage());
} catch (GeneralSecurityException e) {
Log.e("ERROR WHILE CONVERTING PHOTO", e.getMessage());
new RuntimeException(e.getMessage());
}
}
protected Bitmap decodeStreamToBitMap(InputStream inputStream){
return BitmapFactory.decodeStream(inputStream);
}
}