1666ea1b28a76aeba74744148b15099254d918671Owen Lin/* 2666ea1b28a76aeba74744148b15099254d918671Owen Lin * Copyright (C) 2009 The Android Open Source Project 3666ea1b28a76aeba74744148b15099254d918671Owen Lin * 4666ea1b28a76aeba74744148b15099254d918671Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5666ea1b28a76aeba74744148b15099254d918671Owen Lin * you may not use this file except in compliance with the License. 6666ea1b28a76aeba74744148b15099254d918671Owen Lin * You may obtain a copy of the License at 7666ea1b28a76aeba74744148b15099254d918671Owen Lin * 8666ea1b28a76aeba74744148b15099254d918671Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9666ea1b28a76aeba74744148b15099254d918671Owen Lin * 10666ea1b28a76aeba74744148b15099254d918671Owen Lin * Unless required by applicable law or agreed to in writing, software 11666ea1b28a76aeba74744148b15099254d918671Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12666ea1b28a76aeba74744148b15099254d918671Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13666ea1b28a76aeba74744148b15099254d918671Owen Lin * See the License for the specific language governing permissions and 14666ea1b28a76aeba74744148b15099254d918671Owen Lin * limitations under the License. 15666ea1b28a76aeba74744148b15099254d918671Owen Lin */ 16666ea1b28a76aeba74744148b15099254d918671Owen Lin 17666ea1b28a76aeba74744148b15099254d918671Owen Linpackage com.android.camera.gallery; 18666ea1b28a76aeba74744148b15099254d918671Owen Lin 19666ea1b28a76aeba74744148b15099254d918671Owen Linimport com.android.camera.BitmapManager; 20666ea1b28a76aeba74744148b15099254d918671Owen Linimport com.android.camera.Util; 21666ea1b28a76aeba74744148b15099254d918671Owen Lin 22666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.ContentResolver; 23666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.Bitmap; 24666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.BitmapFactory; 25666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.net.Uri; 26666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.os.ParcelFileDescriptor; 27666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.provider.MediaStore.Images; 28666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.util.Log; 29666ea1b28a76aeba74744148b15099254d918671Owen Lin 30666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.io.FileNotFoundException; 31666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.io.IOException; 32666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.io.InputStream; 33666ea1b28a76aeba74744148b15099254d918671Owen Lin 34666ea1b28a76aeba74744148b15099254d918671Owen Lin/** 35666ea1b28a76aeba74744148b15099254d918671Owen Lin * Represents a particular image and provides access to the underlying bitmap 36666ea1b28a76aeba74744148b15099254d918671Owen Lin * and two thumbnail bitmaps as well as other information such as the id, and 37666ea1b28a76aeba74744148b15099254d918671Owen Lin * the path to the actual image data. 38666ea1b28a76aeba74744148b15099254d918671Owen Lin */ 39666ea1b28a76aeba74744148b15099254d918671Owen Linpublic abstract class BaseImage implements IImage { 40666ea1b28a76aeba74744148b15099254d918671Owen Lin private static final String TAG = "BaseImage"; 41666ea1b28a76aeba74744148b15099254d918671Owen Lin private static final int UNKNOWN_LENGTH = -1; 42666ea1b28a76aeba74744148b15099254d918671Owen Lin protected ContentResolver mContentResolver; 43666ea1b28a76aeba74744148b15099254d918671Owen Lin 44666ea1b28a76aeba74744148b15099254d918671Owen Lin // Database field 45666ea1b28a76aeba74744148b15099254d918671Owen Lin protected Uri mUri; 46666ea1b28a76aeba74744148b15099254d918671Owen Lin protected long mId; 47666ea1b28a76aeba74744148b15099254d918671Owen Lin protected String mDataPath; 48666ea1b28a76aeba74744148b15099254d918671Owen Lin protected final int mIndex; 49666ea1b28a76aeba74744148b15099254d918671Owen Lin protected String mMimeType; 50666ea1b28a76aeba74744148b15099254d918671Owen Lin private final long mDateTaken; 51666ea1b28a76aeba74744148b15099254d918671Owen Lin private String mTitle; 52666ea1b28a76aeba74744148b15099254d918671Owen Lin 53666ea1b28a76aeba74744148b15099254d918671Owen Lin protected BaseImageList mContainer; 54666ea1b28a76aeba74744148b15099254d918671Owen Lin 55666ea1b28a76aeba74744148b15099254d918671Owen Lin private int mWidth = UNKNOWN_LENGTH; 56666ea1b28a76aeba74744148b15099254d918671Owen Lin private int mHeight = UNKNOWN_LENGTH; 57666ea1b28a76aeba74744148b15099254d918671Owen Lin 58666ea1b28a76aeba74744148b15099254d918671Owen Lin protected BaseImage(BaseImageList container, ContentResolver cr, 59b62254a185d04ecfe2ddc837b7e0e54f0273c478Owen Lin long id, int index, Uri uri, String dataPath, String mimeType, 60185a1a7c5f33ecc5cb9a36d23cecb719c8727178Chih-Chung Chang long dateTaken, String title) { 61666ea1b28a76aeba74744148b15099254d918671Owen Lin mContainer = container; 62666ea1b28a76aeba74744148b15099254d918671Owen Lin mContentResolver = cr; 63666ea1b28a76aeba74744148b15099254d918671Owen Lin mId = id; 64666ea1b28a76aeba74744148b15099254d918671Owen Lin mIndex = index; 65666ea1b28a76aeba74744148b15099254d918671Owen Lin mUri = uri; 66666ea1b28a76aeba74744148b15099254d918671Owen Lin mDataPath = dataPath; 67666ea1b28a76aeba74744148b15099254d918671Owen Lin mMimeType = mimeType; 68666ea1b28a76aeba74744148b15099254d918671Owen Lin mDateTaken = dateTaken; 69666ea1b28a76aeba74744148b15099254d918671Owen Lin mTitle = title; 70666ea1b28a76aeba74744148b15099254d918671Owen Lin } 71666ea1b28a76aeba74744148b15099254d918671Owen Lin 72666ea1b28a76aeba74744148b15099254d918671Owen Lin public String getDataPath() { 73666ea1b28a76aeba74744148b15099254d918671Owen Lin return mDataPath; 74666ea1b28a76aeba74744148b15099254d918671Owen Lin } 75666ea1b28a76aeba74744148b15099254d918671Owen Lin 76666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 77666ea1b28a76aeba74744148b15099254d918671Owen Lin public boolean equals(Object other) { 78666ea1b28a76aeba74744148b15099254d918671Owen Lin if (other == null || !(other instanceof Image)) return false; 79666ea1b28a76aeba74744148b15099254d918671Owen Lin return mUri.equals(((Image) other).mUri); 80666ea1b28a76aeba74744148b15099254d918671Owen Lin } 81666ea1b28a76aeba74744148b15099254d918671Owen Lin 82666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 83666ea1b28a76aeba74744148b15099254d918671Owen Lin public int hashCode() { 84666ea1b28a76aeba74744148b15099254d918671Owen Lin return mUri.hashCode(); 85666ea1b28a76aeba74744148b15099254d918671Owen Lin } 86666ea1b28a76aeba74744148b15099254d918671Owen Lin 87666ea1b28a76aeba74744148b15099254d918671Owen Lin public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels) { 88666ea1b28a76aeba74744148b15099254d918671Owen Lin return fullSizeBitmap(minSideLength, maxNumberOfPixels, 89666ea1b28a76aeba74744148b15099254d918671Owen Lin IImage.ROTATE_AS_NEEDED, IImage.NO_NATIVE); 90666ea1b28a76aeba74744148b15099254d918671Owen Lin } 91666ea1b28a76aeba74744148b15099254d918671Owen Lin 92666ea1b28a76aeba74744148b15099254d918671Owen Lin public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels, 93666ea1b28a76aeba74744148b15099254d918671Owen Lin boolean rotateAsNeeded, boolean useNative) { 94666ea1b28a76aeba74744148b15099254d918671Owen Lin Uri url = mContainer.contentUri(mId); 95666ea1b28a76aeba74744148b15099254d918671Owen Lin if (url == null) return null; 96666ea1b28a76aeba74744148b15099254d918671Owen Lin 97666ea1b28a76aeba74744148b15099254d918671Owen Lin Bitmap b = Util.makeBitmap(minSideLength, maxNumberOfPixels, 98666ea1b28a76aeba74744148b15099254d918671Owen Lin url, mContentResolver, useNative); 99666ea1b28a76aeba74744148b15099254d918671Owen Lin 100666ea1b28a76aeba74744148b15099254d918671Owen Lin if (b != null && rotateAsNeeded) { 101666ea1b28a76aeba74744148b15099254d918671Owen Lin b = Util.rotate(b, getDegreesRotated()); 102666ea1b28a76aeba74744148b15099254d918671Owen Lin } 103666ea1b28a76aeba74744148b15099254d918671Owen Lin 104666ea1b28a76aeba74744148b15099254d918671Owen Lin return b; 105666ea1b28a76aeba74744148b15099254d918671Owen Lin } 106666ea1b28a76aeba74744148b15099254d918671Owen Lin 107666ea1b28a76aeba74744148b15099254d918671Owen Lin public InputStream fullSizeImageData() { 108666ea1b28a76aeba74744148b15099254d918671Owen Lin try { 109666ea1b28a76aeba74744148b15099254d918671Owen Lin InputStream input = mContentResolver.openInputStream(mUri); 110666ea1b28a76aeba74744148b15099254d918671Owen Lin return input; 111666ea1b28a76aeba74744148b15099254d918671Owen Lin } catch (IOException ex) { 112666ea1b28a76aeba74744148b15099254d918671Owen Lin return null; 113666ea1b28a76aeba74744148b15099254d918671Owen Lin } 114666ea1b28a76aeba74744148b15099254d918671Owen Lin } 115666ea1b28a76aeba74744148b15099254d918671Owen Lin 116666ea1b28a76aeba74744148b15099254d918671Owen Lin public Uri fullSizeImageUri() { 117666ea1b28a76aeba74744148b15099254d918671Owen Lin return mUri; 118666ea1b28a76aeba74744148b15099254d918671Owen Lin } 119666ea1b28a76aeba74744148b15099254d918671Owen Lin 120666ea1b28a76aeba74744148b15099254d918671Owen Lin public IImageList getContainer() { 121666ea1b28a76aeba74744148b15099254d918671Owen Lin return mContainer; 122666ea1b28a76aeba74744148b15099254d918671Owen Lin } 123666ea1b28a76aeba74744148b15099254d918671Owen Lin 124666ea1b28a76aeba74744148b15099254d918671Owen Lin public long getDateTaken() { 125666ea1b28a76aeba74744148b15099254d918671Owen Lin return mDateTaken; 126666ea1b28a76aeba74744148b15099254d918671Owen Lin } 127666ea1b28a76aeba74744148b15099254d918671Owen Lin 128666ea1b28a76aeba74744148b15099254d918671Owen Lin public int getDegreesRotated() { 129666ea1b28a76aeba74744148b15099254d918671Owen Lin return 0; 130666ea1b28a76aeba74744148b15099254d918671Owen Lin } 131666ea1b28a76aeba74744148b15099254d918671Owen Lin 132666ea1b28a76aeba74744148b15099254d918671Owen Lin public String getMimeType() { 133666ea1b28a76aeba74744148b15099254d918671Owen Lin return mMimeType; 134666ea1b28a76aeba74744148b15099254d918671Owen Lin } 135666ea1b28a76aeba74744148b15099254d918671Owen Lin 136666ea1b28a76aeba74744148b15099254d918671Owen Lin public String getTitle() { 137666ea1b28a76aeba74744148b15099254d918671Owen Lin return mTitle; 138666ea1b28a76aeba74744148b15099254d918671Owen Lin } 139666ea1b28a76aeba74744148b15099254d918671Owen Lin 140666ea1b28a76aeba74744148b15099254d918671Owen Lin private void setupDimension() { 141666ea1b28a76aeba74744148b15099254d918671Owen Lin ParcelFileDescriptor input = null; 142666ea1b28a76aeba74744148b15099254d918671Owen Lin try { 143666ea1b28a76aeba74744148b15099254d918671Owen Lin input = mContentResolver.openFileDescriptor(mUri, "r"); 144666ea1b28a76aeba74744148b15099254d918671Owen Lin BitmapFactory.Options options = new BitmapFactory.Options(); 145666ea1b28a76aeba74744148b15099254d918671Owen Lin options.inJustDecodeBounds = true; 146666ea1b28a76aeba74744148b15099254d918671Owen Lin BitmapManager.instance().decodeFileDescriptor( 147666ea1b28a76aeba74744148b15099254d918671Owen Lin input.getFileDescriptor(), options); 148666ea1b28a76aeba74744148b15099254d918671Owen Lin mWidth = options.outWidth; 149666ea1b28a76aeba74744148b15099254d918671Owen Lin mHeight = options.outHeight; 150666ea1b28a76aeba74744148b15099254d918671Owen Lin } catch (FileNotFoundException ex) { 151666ea1b28a76aeba74744148b15099254d918671Owen Lin mWidth = 0; 152666ea1b28a76aeba74744148b15099254d918671Owen Lin mHeight = 0; 153666ea1b28a76aeba74744148b15099254d918671Owen Lin } finally { 154666ea1b28a76aeba74744148b15099254d918671Owen Lin Util.closeSilently(input); 155666ea1b28a76aeba74744148b15099254d918671Owen Lin } 156666ea1b28a76aeba74744148b15099254d918671Owen Lin } 157666ea1b28a76aeba74744148b15099254d918671Owen Lin 158666ea1b28a76aeba74744148b15099254d918671Owen Lin public int getWidth() { 159666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mWidth == UNKNOWN_LENGTH) setupDimension(); 160666ea1b28a76aeba74744148b15099254d918671Owen Lin return mWidth; 161666ea1b28a76aeba74744148b15099254d918671Owen Lin } 162666ea1b28a76aeba74744148b15099254d918671Owen Lin 163666ea1b28a76aeba74744148b15099254d918671Owen Lin public int getHeight() { 164666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mHeight == UNKNOWN_LENGTH) setupDimension(); 165666ea1b28a76aeba74744148b15099254d918671Owen Lin return mHeight; 166666ea1b28a76aeba74744148b15099254d918671Owen Lin } 167666ea1b28a76aeba74744148b15099254d918671Owen Lin 168666ea1b28a76aeba74744148b15099254d918671Owen Lin public Bitmap miniThumbBitmap() { 169666ea1b28a76aeba74744148b15099254d918671Owen Lin Bitmap b = null; 170666ea1b28a76aeba74744148b15099254d918671Owen Lin try { 171666ea1b28a76aeba74744148b15099254d918671Owen Lin long id = mId; 1728aa3fbcf9a5a0d11acd48861f5167073e3554980Owen Lin b = BitmapManager.instance().getThumbnail(mContentResolver, id, 1738aa3fbcf9a5a0d11acd48861f5167073e3554980Owen Lin Images.Thumbnails.MICRO_KIND, null, false); 174666ea1b28a76aeba74744148b15099254d918671Owen Lin } catch (Throwable ex) { 175666ea1b28a76aeba74744148b15099254d918671Owen Lin Log.e(TAG, "miniThumbBitmap got exception", ex); 176666ea1b28a76aeba74744148b15099254d918671Owen Lin return null; 177666ea1b28a76aeba74744148b15099254d918671Owen Lin } 178666ea1b28a76aeba74744148b15099254d918671Owen Lin if (b != null) { 179666ea1b28a76aeba74744148b15099254d918671Owen Lin b = Util.rotate(b, getDegreesRotated()); 180666ea1b28a76aeba74744148b15099254d918671Owen Lin } 181666ea1b28a76aeba74744148b15099254d918671Owen Lin return b; 182666ea1b28a76aeba74744148b15099254d918671Owen Lin } 183666ea1b28a76aeba74744148b15099254d918671Owen Lin 184666ea1b28a76aeba74744148b15099254d918671Owen Lin protected void onRemove() { 185666ea1b28a76aeba74744148b15099254d918671Owen Lin } 186666ea1b28a76aeba74744148b15099254d918671Owen Lin 187666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 188666ea1b28a76aeba74744148b15099254d918671Owen Lin public String toString() { 189666ea1b28a76aeba74744148b15099254d918671Owen Lin return mUri.toString(); 190666ea1b28a76aeba74744148b15099254d918671Owen Lin } 191666ea1b28a76aeba74744148b15099254d918671Owen Lin} 192