1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera.gallery; 18 19 import com.android.camera.BitmapManager; 20 import com.android.camera.Util; 21 22 import android.content.ContentResolver; 23 import android.content.ContentValues; 24 import android.graphics.Bitmap; 25 import android.graphics.BitmapFactory; 26 import android.media.ExifInterface; 27 import android.net.Uri; 28 import android.provider.BaseColumns; 29 import android.provider.MediaStore.Images; 30 import android.provider.MediaStore.Images.ImageColumns; 31 import android.util.Log; 32 33 import java.io.IOException; 34 35 /** 36 * The class for normal images in gallery. 37 */ 38 public class Image extends BaseImage implements IImage { 39 private static final String TAG = "BaseImage"; 40 41 private ExifInterface mExif; 42 43 private int mRotation; 44 45 public Image(BaseImageList container, ContentResolver cr, 46 long id, int index, Uri uri, String dataPath, 47 String mimeType, long dateTaken, String title, 48 int rotation) { 49 super(container, cr, id, index, uri, dataPath, 50 mimeType, dateTaken, title); 51 mRotation = rotation; 52 } 53 54 @Override 55 public int getDegreesRotated() { 56 return mRotation; 57 } 58 59 protected void setDegreesRotated(int degrees) { 60 if (mRotation == degrees) return; 61 mRotation = degrees; 62 ContentValues values = new ContentValues(); 63 values.put(ImageColumns.ORIENTATION, mRotation); 64 mContentResolver.update(mUri, values, null, null); 65 66 //TODO: Consider invalidate the cursor in container 67 // ((BaseImageList) getContainer()).invalidateCursor(); 68 } 69 70 public boolean isReadonly() { 71 String mimeType = getMimeType(); 72 return !"image/jpeg".equals(mimeType) && !"image/png".equals(mimeType); 73 } 74 75 public boolean isDrm() { 76 return false; 77 } 78 79 /** 80 * Replaces the tag if already there. Otherwise, adds to the exif tags. 81 * @param tag 82 * @param value 83 */ 84 public void replaceExifTag(String tag, String value) { 85 if (mExif == null) { 86 loadExifData(); 87 } 88 mExif.setAttribute(tag, value); 89 } 90 91 private void loadExifData() { 92 try { 93 mExif = new ExifInterface(mDataPath); 94 } catch (IOException ex) { 95 Log.e(TAG, "cannot read exif", ex); 96 } 97 } 98 99 private void saveExifData() throws IOException { 100 if (mExif != null) { 101 mExif.saveAttributes(); 102 } 103 } 104 105 private void setExifRotation(int degrees) { 106 try { 107 degrees %= 360; 108 if (degrees < 0) degrees += 360; 109 110 int orientation = ExifInterface.ORIENTATION_NORMAL; 111 switch (degrees) { 112 case 0: 113 orientation = ExifInterface.ORIENTATION_NORMAL; 114 break; 115 case 90: 116 orientation = ExifInterface.ORIENTATION_ROTATE_90; 117 break; 118 case 180: 119 orientation = ExifInterface.ORIENTATION_ROTATE_180; 120 break; 121 case 270: 122 orientation = ExifInterface.ORIENTATION_ROTATE_270; 123 break; 124 } 125 126 replaceExifTag(ExifInterface.TAG_ORIENTATION, 127 Integer.toString(orientation)); 128 saveExifData(); 129 } catch (Exception ex) { 130 Log.e(TAG, "unable to save exif data with new orientation " 131 + fullSizeImageUri(), ex); 132 } 133 } 134 135 /** 136 * Save the rotated image by updating the Exif "Orientation" tag. 137 * @param degrees 138 */ 139 public boolean rotateImageBy(int degrees) { 140 int newDegrees = (getDegreesRotated() + degrees) % 360; 141 setExifRotation(newDegrees); 142 setDegreesRotated(newDegrees); 143 144 return true; 145 } 146 147 private static final String[] THUMB_PROJECTION = new String[] { 148 BaseColumns._ID, 149 }; 150 151 public Bitmap thumbBitmap(boolean rotateAsNeeded) { 152 Bitmap bitmap = null; 153 BitmapFactory.Options options = new BitmapFactory.Options(); 154 options.inDither = false; 155 options.inPreferredConfig = Bitmap.Config.ARGB_8888; 156 bitmap = BitmapManager.instance().getThumbnail(mContentResolver, mId, 157 Images.Thumbnails.MINI_KIND, options, false); 158 159 if (bitmap != null && rotateAsNeeded) { 160 bitmap = Util.rotate(bitmap, getDegreesRotated()); 161 } 162 163 return bitmap; 164 } 165 } 166