From 3190f6975341d1e726c42c1b86a17b956578a40c Mon Sep 17 00:00:00 2001 From: Owen Lin Date: Fri, 2 Sep 2011 21:15:42 +0800 Subject: Copy exif data for cropped image. fix: 5248023 Change-Id: I2f59bfd96ca7533195f7019cc76080579dff8d1e --- src/com/android/gallery3d/app/CropImage.java | 92 ++++++++++++++++++++++ src/com/android/gallery3d/util/GalleryUtils.java | 19 +++++ .../gallery3d/picasasource/PicasaSource.java | 3 + 3 files changed, 114 insertions(+) diff --git a/src/com/android/gallery3d/app/CropImage.java b/src/com/android/gallery3d/app/CropImage.java index 6c0a0c7eb..47c007b8d 100644 --- a/src/com/android/gallery3d/app/CropImage.java +++ b/src/com/android/gallery3d/app/CropImage.java @@ -51,6 +51,7 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; +import android.media.ExifInterface; import android.net.Uri; import android.os.Bundle; import android.os.Environment; @@ -347,6 +348,8 @@ public class CropImage extends AbstractGalleryActivity { File output = saveMedia(jc, cropped, DOWNLOAD_BUCKET, filename); if (output == null) return null; + copyExif(mMediaItem, output.getAbsolutePath(), cropped.getWidth(), cropped.getHeight()); + long now = System.currentTimeMillis() / 1000; ContentValues values = new ContentValues(); values.put(Images.Media.TITLE, PicasaSource.getImageTitle(mMediaItem)); @@ -381,6 +384,9 @@ public class CropImage extends AbstractGalleryActivity { File output = saveMedia(jc, cropped, directory, filename); if (output == null) return null; + copyExif(oldPath.getAbsolutePath(), output.getAbsolutePath(), + cropped.getWidth(), cropped.getHeight()); + long now = System.currentTimeMillis() / 1000; ContentValues values = new ContentValues(); values.put(Images.Media.TITLE, localImage.caption); @@ -847,4 +853,90 @@ public class CropImage extends AbstractGalleryActivity { : mItem.requestImage(MediaItem.TYPE_THUMBNAIL).run(jc); } } + + private static final String[] EXIF_TAGS = { + ExifInterface.TAG_DATETIME, + ExifInterface.TAG_MAKE, + ExifInterface.TAG_MODEL, + ExifInterface.TAG_FLASH, + ExifInterface.TAG_GPS_LATITUDE, + ExifInterface.TAG_GPS_LONGITUDE, + ExifInterface.TAG_GPS_LATITUDE_REF, + ExifInterface.TAG_GPS_LONGITUDE_REF, + ExifInterface.TAG_GPS_ALTITUDE, + ExifInterface.TAG_GPS_ALTITUDE_REF, + ExifInterface.TAG_GPS_TIMESTAMP, + ExifInterface.TAG_GPS_DATESTAMP, + ExifInterface.TAG_WHITE_BALANCE, + ExifInterface.TAG_FOCAL_LENGTH, + ExifInterface.TAG_GPS_PROCESSING_METHOD}; + + private static void copyExif(MediaItem item, String destination, int newWidth, int newHeight) { + try { + ExifInterface newExif = new ExifInterface(destination); + PicasaSource.extractExifValues(item, newExif); + newExif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH, String.valueOf(newWidth)); + newExif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH, String.valueOf(newHeight)); + newExif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(0)); + newExif.saveAttributes(); + } catch (Throwable t) { + Log.w(TAG, "cannot copy exif: " + item, t); + } + } + + private static void copyExif(String source, String destination, int newWidth, int newHeight) { + try { + ExifInterface oldExif = new ExifInterface(source); + ExifInterface newExif = new ExifInterface(destination); + + newExif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH, String.valueOf(newWidth)); + newExif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH, String.valueOf(newHeight)); + newExif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(0)); + + for (String tag : EXIF_TAGS) { + String value = oldExif.getAttribute(tag); + if (value != null) { + newExif.setAttribute(tag, value); + } + } + + // Handle some special values here + String value = oldExif.getAttribute(ExifInterface.TAG_APERTURE); + if (value != null) { + try { + float aperture = Float.parseFloat(value); + newExif.setAttribute(ExifInterface.TAG_APERTURE, + String.valueOf((int) (aperture * 10 + 0.5f)) + "/10"); + } catch (NumberFormatException e) { + Log.w(TAG, "cannot parse aperture: " + value); + } + } + + // TODO: The code is broken, need to fix the JHEAD lib + /* + value = oldExif.getAttribute(ExifInterface.TAG_EXPOSURE_TIME); + if (value != null) { + try { + double exposure = Double.parseDouble(value); + testToRational("test exposure", exposure); + newExif.setAttribute(ExifInterface.TAG_EXPOSURE_TIME, value); + } catch (NumberFormatException e) { + Log.w(TAG, "cannot parse exposure time: " + value); + } + } + + value = oldExif.getAttribute(ExifInterface.TAG_ISO); + if (value != null) { + try { + int iso = Integer.parseInt(value); + newExif.setAttribute(ExifInterface.TAG_ISO, String.valueOf(iso) + "/1"); + } catch (NumberFormatException e) { + Log.w(TAG, "cannot parse exposure time: " + value); + } + }*/ + newExif.saveAttributes(); + } catch (Throwable t) { + Log.w(TAG, "cannot copy exif: " + source, t); + } + } } diff --git a/src/com/android/gallery3d/util/GalleryUtils.java b/src/com/android/gallery3d/util/GalleryUtils.java index 47beb2d09..9c08deaa5 100644 --- a/src/com/android/gallery3d/util/GalleryUtils.java +++ b/src/com/android/gallery3d/util/GalleryUtils.java @@ -333,4 +333,23 @@ public class GalleryUtils { throw new AssertionError(); } } + + public static void doubleToRational(double value, long[] output) { + // error is a magic number to control the tollerance of error + doubleToRational(value, output, 0.00001); + } + + private static void doubleToRational(double value, long[] output, double error) { + long number = (long) value; + value -= number; + if (value < 0.000001 || error > 1) { + output[0] = (int) (number + value + 0.5); + output[1] = 1; + } else { + doubleToRational(1.0 / value, output, error / value); + number = number * output[0] + output[1]; + output[1] = output[0]; + output[0] = number; + } + } } diff --git a/src_pd/com/android/gallery3d/picasasource/PicasaSource.java b/src_pd/com/android/gallery3d/picasasource/PicasaSource.java index 4918d72dc..ed90ea60e 100644 --- a/src_pd/com/android/gallery3d/picasasource/PicasaSource.java +++ b/src_pd/com/android/gallery3d/picasasource/PicasaSource.java @@ -24,6 +24,7 @@ import com.android.gallery3d.data.Path; import com.android.gallery3d.data.PathMatcher; import android.content.Context; +import android.media.ExifInterface; import android.os.ParcelFileDescriptor; import java.io.FileNotFoundException; @@ -122,4 +123,6 @@ public class PicasaSource extends MediaSource { public static void onPackageAdded(Context context, String packageName) {/*do nothing*/} public static void onPackageRemoved(Context context, String packageName) {/*do nothing*/} + + public static void extractExifValues(MediaObject item, ExifInterface exif) {/*do nothing*/} } -- cgit v1.2.3