blob: 2ae8e2089725af177c4bf688f34de861682ed8bd [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.camera;
import android.content.ContentResolver;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.media.ThumbnailUtil;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/** A controller shows thumbnail picture on a button. The thumbnail picture
* corresponds to a URI of the original picture/video. The thumbnail bitmap
* and the URI can be saved to a file (and later loaded from it).
* <pre>
* public ThumbnailController(ImageView button)
* public void setData(Uri uri, Bitmap original)
* public void updateDisplayIfNeeded()
* public Uri getUri()
* public boolean storeData(String filePath)
* public boolean loadData(String filePath)
* </pre>
*/
public class ThumbnailController {
@SuppressWarnings("unused")
private static final String TAG = "ThumbnailController";
private final ContentResolver mContentResolver;
private Uri mUri;
private Bitmap mThumb;
private final ImageView mButton;
private Drawable[] mThumbs;
private TransitionDrawable mThumbTransition;
private boolean mShouldAnimateThumb;
private final Resources mResources;
// The "frame" is a drawable we want to put on top of the thumbnail.
public ThumbnailController(Resources resources,
ImageView button, ContentResolver contentResolver) {
mResources = resources;
mButton = button;
mContentResolver = contentResolver;
}
public void setData(Uri uri, Bitmap original) {
// Make sure uri and original are consistently both null or both
// non-null.
if (uri == null || original == null) {
uri = null;
original = null;
}
mUri = uri;
updateThumb(original);
}
public Uri getUri() {
return mUri;
}
private static final int BUFSIZE = 4096;
// Stores the data from the specified file.
// Returns true for success.
public boolean storeData(String filePath) {
if (mUri == null) {
return false;
}
FileOutputStream f = null;
BufferedOutputStream b = null;
DataOutputStream d = null;
try {
f = new FileOutputStream(filePath);
b = new BufferedOutputStream(f, BUFSIZE);
d = new DataOutputStream(b);
d.writeUTF(mUri.toString());
mThumb.compress(Bitmap.CompressFormat.PNG, 100, d);
d.close();
} catch (IOException e) {
return false;
} finally {
MenuHelper.closeSilently(f);
MenuHelper.closeSilently(b);
MenuHelper.closeSilently(d);
}
return true;
}
// Loads the data from the specified file.
// Returns true for success.
public boolean loadData(String filePath) {
FileInputStream f = null;
BufferedInputStream b = null;
DataInputStream d = null;
try {
f = new FileInputStream(filePath);
b = new BufferedInputStream(f, BUFSIZE);
d = new DataInputStream(b);
Uri uri = Uri.parse(d.readUTF());
Bitmap thumb = BitmapFactory.decodeStream(d);
setData(uri, thumb);
d.close();
} catch (IOException e) {
return false;
} finally {
MenuHelper.closeSilently(f);
MenuHelper.closeSilently(b);
MenuHelper.closeSilently(d);
}
return true;
}
public void updateDisplayIfNeeded() {
if (mUri == null) {
mButton.setImageDrawable(null);
return;
}
if (mShouldAnimateThumb) {
mThumbTransition.startTransition(500);
mShouldAnimateThumb = false;
}
}
private void updateThumb(Bitmap original) {
if (original == null) {
mThumb = null;
mThumbs = null;
return;
}
// Make the mini-thumb size smaller than the button size so that the
// image corners don't peek out from the rounded corners of the
// frame_thumb graphic:
final int PADDING_WIDTH = 2;
final int PADDING_HEIGHT = 2;
LayoutParams param = mButton.getLayoutParams();
final int miniThumbWidth = param.width - 2 * PADDING_WIDTH;
final int miniThumbHeight = param.height - 2 * PADDING_HEIGHT;
mThumb = ThumbnailUtil.extractMiniThumb(
original, miniThumbWidth, miniThumbHeight,
Util.NO_RECYCLE_INPUT);
Drawable drawable;
if (mThumbs == null) {
mThumbs = new Drawable[2];
mThumbs[1] = new BitmapDrawable(mResources, mThumb);
drawable = mThumbs[1];
mShouldAnimateThumb = false;
} else {
mThumbs[0] = mThumbs[1];
mThumbs[1] = new BitmapDrawable(mResources, mThumb);
mThumbTransition = new TransitionDrawable(mThumbs);
drawable = mThumbTransition;
mShouldAnimateThumb = true;
}
mButton.setImageDrawable(drawable);
}
public boolean isUriValid() {
if (mUri == null) {
return false;
}
try {
ParcelFileDescriptor pfd =
mContentResolver.openFileDescriptor(mUri, "r");
if (pfd == null) {
Log.e(TAG, "Fail to open URI.");
return false;
}
pfd.close();
} catch (IOException ex) {
return false;
}
return true;
}
}