Skip to content

Commit

Permalink
imageCaptureProcessing maintain EXIF
Browse files Browse the repository at this point in the history
Change requests

change request

SuppressLint

SuppressLint imageCaptureProcessing.java
  • Loading branch information
melmathari committed Nov 25, 2024
1 parent ce9dfca commit 2070680
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class ImageCaptureProcessing {
* @return A pair containing raw image and scaled imagePath. The first entry is the raw image
* while the second one is path to scaled image.
*/
@SuppressLint("ExifInterface")
private static Pair<File, String> moveAndScaleImage(File originalImage, boolean shouldScale,
String instanceFolder,
FormEntryActivity formEntryActivity) throws IOException {
Expand All @@ -56,7 +57,8 @@ private static Pair<File, String> moveAndScaleImage(File originalImage, boolean
if (currentWidget != null) {
int maxDimen = currentWidget.getMaxDimen();
if (maxDimen != -1) {
savedScaledImage = FileUtil.scaleAndSaveImage(originalImage, tempFilePathForScaledImage, maxDimen);
File tempFile = new File(tempFilePathForScaledImage);
savedScaledImage = FileUtil.scaleAndSaveImageWithExif(originalImage, tempFile, maxDimen);
}
}
}
Expand All @@ -83,6 +85,7 @@ private static Pair<File, String> moveAndScaleImage(File originalImage, boolean
return new Pair<>(rawImageFile, finalFilePath);
}

@SuppressLint("ExifInterface")
private static File makeRawCopy(File originalImage, String instanceFolder, String imageFilename)
throws IOException {
String rawDirPath = getRawDirectoryPath(instanceFolder);
Expand All @@ -92,7 +95,7 @@ private static File makeRawCopy(File originalImage, String instanceFolder, Strin
}
File rawImageFile = new File(rawDirPath + "/" + imageFilename);
try {
FileUtil.copyFile(originalImage, rawImageFile);
FileUtil.copyFileWithExifData(originalImage, rawImageFile);
} catch (Exception e) {
throw new IOException("Failed to rename " + originalImage.getAbsolutePath() +
" to " + rawImageFile.getAbsolutePath());
Expand Down Expand Up @@ -208,6 +211,7 @@ private static void processImageGivenFilePath(FormEntryActivity activity, String
}
}

@SuppressLint("ExifInterface")
private static boolean scaleAndSaveImage(File originalImage, boolean shouldScale,
String instanceFolder, FormEntryActivity activity) throws IOException {
Pair<File, String> rawImageAndScaledPath = moveAndScaleImage(originalImage, shouldScale, instanceFolder, activity);
Expand Down
93 changes: 83 additions & 10 deletions app/src/org/commcare/utils/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.ExifInterface;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
Expand Down Expand Up @@ -356,17 +357,16 @@ public static String getGlobalStringUri(String fileLocation) {
}

public static void checkReferenceURI(Resource r, String URI, Vector<MissingMediaException> problems) throws InvalidReferenceException {
Reference mRef = ReferenceManager.instance().DeriveReference(URI);
Reference mRef = ReferenceManager.instance().DeriveReference(uri);
String mLocalReference = mRef.getLocalURI();
try {
if (!mRef.doesBinaryExist()) {
problems.addElement(new MissingMediaException(r, "Missing external media: " + mLocalReference, URI,
MissingMediaException.MissingMediaExceptionType.FILE_NOT_FOUND));
throw new InvalidReferenceException("Missing external media: " + mLocalReference);
}
} catch (IOException e) {
problems.addElement(new MissingMediaException(r, "Problem reading external media: " + mLocalReference, URI,
MissingMediaException.MissingMediaExceptionType.FILE_NOT_ACCESSIBLE));
throw new InvalidReferenceException("Problem reading external media: " + mLocalReference);
}
return mRef;
}

public static boolean referenceFileExists(String uri) {
Expand Down Expand Up @@ -494,8 +494,9 @@ public static String getMd5Hash(File file) {

BigInteger number = new BigInteger(1, messageDigest);
String md5 = number.toString(16);
while (md5.length() < 32)
while (md5.length() < 32) {
md5 = "0" + md5;
}
is.close();
return md5;

Expand Down Expand Up @@ -612,7 +613,8 @@ public static boolean scaleAndSaveImage(File originalImage, String finalFilePath
Pair<Bitmap, Boolean> bitmapAndScaledBool = MediaUtil.inflateImageSafe(originalImage.getAbsolutePath());
if (bitmapAndScaledBool.second) {
Logger.log(LogTypes.TYPE_FORM_ENTRY,
"An image captured during form entry was too large to be processed at its original size, and had to be downsized");
"An image captured during form entry was too large to be processed at its original size, " +
"and had to be downsized");
}
Bitmap scaledBitmap = getBitmapScaledByMaxDimen(bitmapAndScaledBool.first, maxDimen);
if (scaledBitmap != null) {
Expand Down Expand Up @@ -723,7 +725,9 @@ public static Uri getUriForExternalFile(Context context, File file) {
* @param dstFile destination File where we need to copy the inputStream
*/
public static void copyFile(InputStream inputStream, File dstFile) throws IOException {
if (inputStream == null) return;
if (inputStream == null) {
return;
}
OutputStream outputStream = new FileOutputStream(dstFile);
StreamsUtil.writeFromInputToOutputUnmanaged(inputStream, outputStream);
inputStream.close();
Expand Down Expand Up @@ -844,8 +848,13 @@ public static void addMediaToGallery(Context context, File file) throws
}

/**
* Returns true only when we're certain that the file size is too large.
* <p> https://developer.android.com/training/secure-file-sharing/retrieve-info.html#RetrieveFileInfo
* Checks if a file referenced by a content URI exceeds the maximum allowed upload size
* <p>
* @param contentResolver ContentResolver to query the file size
* @param uri Content URI of the file to check
* @return true if the file size exceeds FormUploadUtil.MAX_BYTES, false otherwise or if size cannot be determined
* @see FormUploadUtil#MAX_BYTES
* @see <a href="https://developer.android.com/training/secure-file-sharing/retrieve-info.html#RetrieveFileInfo">Android docs</a>
*/
public static boolean isFileTooLargeToUpload(ContentResolver contentResolver, Uri uri) {
try (Cursor returnCursor = contentResolver.query(uri, null, null, null, null)) {
Expand All @@ -857,4 +866,68 @@ public static boolean isFileTooLargeToUpload(ContentResolver contentResolver, Ur
return returnCursor.getLong(sizeIndex) > FormUploadUtil.MAX_BYTES;
}
}

@SuppressLint("ExifInterface")
public static void copyFileWithExifData(File sourceFile, File destFile) throws IOException {
// First copy the file normally
copyFile(sourceFile, destFile);

// Then copy EXIF data
copyExifData(sourceFile.getAbsolutePath(), destFile.getAbsolutePath());
}

@SuppressLint("ExifInterface")
public static boolean scaleAndSaveImageWithExif(File sourceFile, File destFile, int maxDimen) throws IOException {
// First scale the image
boolean scaled = scaleAndSaveImage(sourceFile, destFile.getAbsolutePath(), maxDimen);

if (scaled) {
// Copy EXIF data from source to scaled image
copyExifData(sourceFile.getAbsolutePath(), destFile.getAbsolutePath());
}

return scaled;
}

@SuppressLint("ExifInterface")
private static void copyExifData(String sourcePath, String destPath) throws IOException {
ExifInterface source = new ExifInterface(sourcePath);
ExifInterface dest = new ExifInterface(destPath);

String[] tagsToPreserve = {
// GPS data
ExifInterface.TAG_GPS_LATITUDE,
ExifInterface.TAG_GPS_LATITUDE_REF,
ExifInterface.TAG_GPS_LONGITUDE,
ExifInterface.TAG_GPS_LONGITUDE_REF,
ExifInterface.TAG_GPS_TIMESTAMP,
ExifInterface.TAG_GPS_DATESTAMP,
ExifInterface.TAG_GPS_ALTITUDE,
ExifInterface.TAG_GPS_ALTITUDE_REF,
ExifInterface.TAG_GPS_AREA_INFORMATION,

// Timestamp data
ExifInterface.TAG_DATETIME,
ExifInterface.TAG_DATETIME_DIGITIZED,
ExifInterface.TAG_DATETIME_ORIGINAL,
ExifInterface.TAG_OFFSET_TIME,
ExifInterface.TAG_OFFSET_TIME_ORIGINAL,
ExifInterface.TAG_OFFSET_TIME_DIGITIZED,

// Image metadata
ExifInterface.TAG_COPYRIGHT,
ExifInterface.TAG_IMAGE_DESCRIPTION,
ExifInterface.TAG_EXIF_VERSION,
ExifInterface.TAG_ORIENTATION
};

for (String tag : tagsToPreserve) {
String value = source.getAttribute(tag);
if (value != null) {
dest.setAttribute(tag, value);
}
}

dest.saveAttributes();
}
}

0 comments on commit 2070680

Please sign in to comment.