blob: 2ae8e2089725af177c4bf688f34de861682ed8bd [file] [log] [blame]
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -07001/*
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
17package com.android.camera;
18
Owen Lin101d5282009-04-03 16:20:08 -070019
Chih-Chung Chang0435bac2009-04-01 00:11:56 -070020import android.content.ContentResolver;
Owen Line594b192009-08-13 18:04:45 +080021import android.content.res.Resources;
Chih-Chung Chang0435bac2009-04-01 00:11:56 -070022import android.graphics.Bitmap;
23import android.graphics.BitmapFactory;
24import android.graphics.drawable.BitmapDrawable;
25import android.graphics.drawable.Drawable;
Chih-Chung Chang0435bac2009-04-01 00:11:56 -070026import android.graphics.drawable.TransitionDrawable;
Ray Chen9f1480b2009-08-27 17:59:29 -070027import android.media.ThumbnailUtil;
Chih-Chung Chang0435bac2009-04-01 00:11:56 -070028import android.net.Uri;
Wu-cheng Li8d16a5c2009-06-18 16:37:32 +080029import android.os.ParcelFileDescriptor;
30import android.util.Log;
Chih-Chung Chang0435bac2009-04-01 00:11:56 -070031import android.view.ViewGroup.LayoutParams;
Chih-Chung Chang0435bac2009-04-01 00:11:56 -070032import android.widget.ImageView;
33
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070034import java.io.BufferedInputStream;
35import java.io.BufferedOutputStream;
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070036import java.io.DataInputStream;
37import java.io.DataOutputStream;
38import java.io.FileInputStream;
39import java.io.FileOutputStream;
40import java.io.IOException;
41
Chih-Chung Chang0435bac2009-04-01 00:11:56 -070042/** A controller shows thumbnail picture on a button. The thumbnail picture
43 * corresponds to a URI of the original picture/video. The thumbnail bitmap
44 * and the URI can be saved to a file (and later loaded from it).
45 * <pre>
46 * public ThumbnailController(ImageView button)
47 * public void setData(Uri uri, Bitmap original)
48 * public void updateDisplayIfNeeded()
49 * public Uri getUri()
Chih-Chung Chang0435bac2009-04-01 00:11:56 -070050 * public boolean storeData(String filePath)
51 * public boolean loadData(String filePath)
52 * </pre>
53 */
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070054public class ThumbnailController {
Owen Lin937fc482009-04-14 02:02:51 -070055
56 @SuppressWarnings("unused")
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070057 private static final String TAG = "ThumbnailController";
Owen Lin059daa32009-05-18 15:31:17 -070058 private final ContentResolver mContentResolver;
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070059 private Uri mUri;
60 private Bitmap mThumb;
Owen Lin059daa32009-05-18 15:31:17 -070061 private final ImageView mButton;
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070062 private Drawable[] mThumbs;
63 private TransitionDrawable mThumbTransition;
64 private boolean mShouldAnimateThumb;
Owen Line594b192009-08-13 18:04:45 +080065 private final Resources mResources;
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070066
67 // The "frame" is a drawable we want to put on top of the thumbnail.
Owen Line594b192009-08-13 18:04:45 +080068 public ThumbnailController(Resources resources,
Owen Lin059daa32009-05-18 15:31:17 -070069 ImageView button, ContentResolver contentResolver) {
Owen Line594b192009-08-13 18:04:45 +080070 mResources = resources;
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070071 mButton = button;
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070072 mContentResolver = contentResolver;
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070073 }
74
75 public void setData(Uri uri, Bitmap original) {
Chih-Chung Chang0435bac2009-04-01 00:11:56 -070076 // Make sure uri and original are consistently both null or both
77 // non-null.
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070078 if (uri == null || original == null) {
79 uri = null;
80 original = null;
81 }
82 mUri = uri;
83 updateThumb(original);
84 }
85
86 public Uri getUri() {
87 return mUri;
88 }
89
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -070090 private static final int BUFSIZE = 4096;
91
92 // Stores the data from the specified file.
93 // Returns true for success.
94 public boolean storeData(String filePath) {
95 if (mUri == null) {
96 return false;
97 }
98
99 FileOutputStream f = null;
100 BufferedOutputStream b = null;
101 DataOutputStream d = null;
102 try {
103 f = new FileOutputStream(filePath);
104 b = new BufferedOutputStream(f, BUFSIZE);
105 d = new DataOutputStream(b);
106 d.writeUTF(mUri.toString());
107 mThumb.compress(Bitmap.CompressFormat.PNG, 100, d);
108 d.close();
109 } catch (IOException e) {
110 return false;
111 } finally {
Chih-Chung Chang272c3fd2009-04-08 05:14:37 -0700112 MenuHelper.closeSilently(f);
113 MenuHelper.closeSilently(b);
114 MenuHelper.closeSilently(d);
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700115 }
116 return true;
117 }
118
119 // Loads the data from the specified file.
120 // Returns true for success.
121 public boolean loadData(String filePath) {
122 FileInputStream f = null;
123 BufferedInputStream b = null;
124 DataInputStream d = null;
125 try {
126 f = new FileInputStream(filePath);
127 b = new BufferedInputStream(f, BUFSIZE);
128 d = new DataInputStream(b);
129 Uri uri = Uri.parse(d.readUTF());
130 Bitmap thumb = BitmapFactory.decodeStream(d);
131 setData(uri, thumb);
132 d.close();
133 } catch (IOException e) {
134 return false;
135 } finally {
Chih-Chung Chang272c3fd2009-04-08 05:14:37 -0700136 MenuHelper.closeSilently(f);
137 MenuHelper.closeSilently(b);
138 MenuHelper.closeSilently(d);
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700139 }
140 return true;
141 }
142
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700143 public void updateDisplayIfNeeded() {
144 if (mUri == null) {
Chih-Chung Changb7b36b92009-09-25 13:32:17 -0700145 mButton.setImageDrawable(null);
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700146 return;
147 }
148
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700149 if (mShouldAnimateThumb) {
150 mThumbTransition.startTransition(500);
151 mShouldAnimateThumb = false;
152 }
153 }
154
155 private void updateThumb(Bitmap original) {
156 if (original == null) {
157 mThumb = null;
158 mThumbs = null;
159 return;
160 }
161
Chih-Chung Chang0435bac2009-04-01 00:11:56 -0700162 // Make the mini-thumb size smaller than the button size so that the
163 // image corners don't peek out from the rounded corners of the
164 // frame_thumb graphic:
Owen Lindad4b182009-06-11 16:02:29 -0700165 final int PADDING_WIDTH = 2;
166 final int PADDING_HEIGHT = 2;
Owen Lin059daa32009-05-18 15:31:17 -0700167 LayoutParams param = mButton.getLayoutParams();
168 final int miniThumbWidth = param.width - 2 * PADDING_WIDTH;
169 final int miniThumbHeight = param.height - 2 * PADDING_HEIGHT;
Ray Chen9f1480b2009-08-27 17:59:29 -0700170 mThumb = ThumbnailUtil.extractMiniThumb(
Chih-Chung Chang34fe2a92009-08-19 15:52:32 +0800171 original, miniThumbWidth, miniThumbHeight,
172 Util.NO_RECYCLE_INPUT);
Owen Lin059daa32009-05-18 15:31:17 -0700173 Drawable drawable;
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700174 if (mThumbs == null) {
175 mThumbs = new Drawable[2];
Owen Line594b192009-08-13 18:04:45 +0800176 mThumbs[1] = new BitmapDrawable(mResources, mThumb);
Owen Lin059daa32009-05-18 15:31:17 -0700177 drawable = mThumbs[1];
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700178 mShouldAnimateThumb = false;
179 } else {
180 mThumbs[0] = mThumbs[1];
Owen Line594b192009-08-13 18:04:45 +0800181 mThumbs[1] = new BitmapDrawable(mResources, mThumb);
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700182 mThumbTransition = new TransitionDrawable(mThumbs);
Owen Lin059daa32009-05-18 15:31:17 -0700183 drawable = mThumbTransition;
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700184 mShouldAnimateThumb = true;
185 }
Owen Lin059daa32009-05-18 15:31:17 -0700186 mButton.setImageDrawable(drawable);
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700187 }
188
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700189 public boolean isUriValid() {
Ray Chen23c51b72009-04-10 03:41:00 -0700190 if (mUri == null) {
191 return false;
192 }
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700193 try {
Wu-cheng Li8d16a5c2009-06-18 16:37:32 +0800194 ParcelFileDescriptor pfd =
195 mContentResolver.openFileDescriptor(mUri, "r");
196 if (pfd == null) {
197 Log.e(TAG, "Fail to open URI.");
198 return false;
199 }
200 pfd.close();
Chih-Chung Chang0435bac2009-04-01 00:11:56 -0700201 } catch (IOException ex) {
Chih-Chung Chang9bc8d1b2009-03-24 19:22:29 -0700202 return false;
203 }
204 return true;
205 }
206}