OSDN Git Service

Copy exif data for cropped image.
authorOwen Lin <owenlin@google.com>
Fri, 2 Sep 2011 13:15:42 +0000 (21:15 +0800)
committerOwen Lin <owenlin@google.com>
Wed, 7 Sep 2011 06:58:36 +0000 (14:58 +0800)
fix: 5248023

Change-Id: I2f59bfd96ca7533195f7019cc76080579dff8d1e

src/com/android/gallery3d/app/CropImage.java
src/com/android/gallery3d/util/GalleryUtils.java
src_pd/com/android/gallery3d/picasasource/PicasaSource.java

index 6c0a0c7..47c007b 100644 (file)
@@ -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);
+        }
+    }
 }
index 47beb2d..9c08dea 100644 (file)
@@ -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;
+        }
+    }
 }
index 4918d72..ed90ea6 100644 (file)
@@ -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*/}
 }