Home | History | Annotate | Download | only in camera
      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;
     18 
     19 
     20 import android.content.ContentResolver;
     21 import android.content.res.Resources;
     22 import android.graphics.Bitmap;
     23 import android.graphics.BitmapFactory;
     24 import android.graphics.drawable.BitmapDrawable;
     25 import android.graphics.drawable.Drawable;
     26 import android.graphics.drawable.TransitionDrawable;
     27 import android.media.ThumbnailUtils;
     28 import android.net.Uri;
     29 import android.os.ParcelFileDescriptor;
     30 import android.util.Log;
     31 import android.view.ViewGroup.LayoutParams;
     32 import android.widget.ImageView;
     33 
     34 import java.io.BufferedInputStream;
     35 import java.io.BufferedOutputStream;
     36 import java.io.DataInputStream;
     37 import java.io.DataOutputStream;
     38 import java.io.FileInputStream;
     39 import java.io.FileOutputStream;
     40 import java.io.IOException;
     41 
     42 /**
     43  * A controller shows thumbnail picture on a button. The thumbnail picture
     44  * corresponds to a URI of the original picture/video. The thumbnail bitmap
     45  * and the URI can be saved to a file (and later loaded from it).
     46  */
     47 public class ThumbnailController {
     48 
     49     @SuppressWarnings("unused")
     50     private static final String TAG = "ThumbnailController";
     51     private final ContentResolver mContentResolver;
     52     private Uri mUri;
     53     private Bitmap mThumb;
     54     private final ImageView mButton;
     55     private Drawable[] mThumbs;
     56     private TransitionDrawable mThumbTransition;
     57     private boolean mShouldAnimateThumb;
     58     private final Resources mResources;
     59 
     60     // The "frame" is a drawable we want to put on top of the thumbnail.
     61     public ThumbnailController(Resources resources,
     62             ImageView button, ContentResolver contentResolver) {
     63         mResources = resources;
     64         mButton = button;
     65         mContentResolver = contentResolver;
     66     }
     67 
     68     public void setData(Uri uri, Bitmap original) {
     69         // Make sure uri and original are consistently both null or both
     70         // non-null.
     71         if (uri == null || original == null) {
     72             uri = null;
     73             original = null;
     74         }
     75         mUri = uri;
     76         updateThumb(original);
     77     }
     78 
     79     public Uri getUri() {
     80         return mUri;
     81     }
     82 
     83     private static final int BUFSIZE = 4096;
     84 
     85     // Stores the data from the specified file.
     86     // Returns true for success.
     87     public boolean storeData(String filePath) {
     88         if (mUri == null) {
     89             return false;
     90         }
     91 
     92         FileOutputStream f = null;
     93         BufferedOutputStream b = null;
     94         DataOutputStream d = null;
     95         try {
     96             f = new FileOutputStream(filePath);
     97             b = new BufferedOutputStream(f, BUFSIZE);
     98             d = new DataOutputStream(b);
     99             d.writeUTF(mUri.toString());
    100             mThumb.compress(Bitmap.CompressFormat.PNG, 100, d);
    101             d.close();
    102         } catch (IOException e) {
    103             return false;
    104         } finally {
    105             MenuHelper.closeSilently(f);
    106             MenuHelper.closeSilently(b);
    107             MenuHelper.closeSilently(d);
    108         }
    109         return true;
    110     }
    111 
    112     // Loads the data from the specified file.
    113     // Returns true for success.
    114     public boolean loadData(String filePath) {
    115         FileInputStream f = null;
    116         BufferedInputStream b = null;
    117         DataInputStream d = null;
    118         try {
    119             f = new FileInputStream(filePath);
    120             b = new BufferedInputStream(f, BUFSIZE);
    121             d = new DataInputStream(b);
    122             Uri uri = Uri.parse(d.readUTF());
    123             Bitmap thumb = BitmapFactory.decodeStream(d);
    124             setData(uri, thumb);
    125             d.close();
    126         } catch (IOException e) {
    127             return false;
    128         } finally {
    129             MenuHelper.closeSilently(f);
    130             MenuHelper.closeSilently(b);
    131             MenuHelper.closeSilently(d);
    132         }
    133         return true;
    134     }
    135 
    136     public void updateDisplayIfNeeded() {
    137         if (mUri == null) {
    138             mButton.setImageDrawable(null);
    139             return;
    140         }
    141 
    142         if (mShouldAnimateThumb) {
    143             mThumbTransition.startTransition(500);
    144             mShouldAnimateThumb = false;
    145         }
    146     }
    147 
    148     private void updateThumb(Bitmap original) {
    149         if (original == null) {
    150             mThumb = null;
    151             mThumbs = null;
    152             return;
    153         }
    154 
    155         LayoutParams param = mButton.getLayoutParams();
    156         final int miniThumbWidth = param.width
    157                 - mButton.getPaddingLeft() - mButton.getPaddingRight();
    158         final int miniThumbHeight = param.height
    159                 - mButton.getPaddingTop() - mButton.getPaddingBottom();
    160         mThumb = ThumbnailUtils.extractThumbnail(
    161                 original, miniThumbWidth, miniThumbHeight);
    162         Drawable drawable;
    163         if (mThumbs == null) {
    164             mThumbs = new Drawable[2];
    165             mThumbs[1] = new BitmapDrawable(mResources, mThumb);
    166             drawable = mThumbs[1];
    167             mShouldAnimateThumb = false;
    168         } else {
    169             mThumbs[0] = mThumbs[1];
    170             mThumbs[1] = new BitmapDrawable(mResources, mThumb);
    171             mThumbTransition = new TransitionDrawable(mThumbs);
    172             drawable = mThumbTransition;
    173             mShouldAnimateThumb = true;
    174         }
    175         mButton.setImageDrawable(drawable);
    176     }
    177 
    178     public boolean isUriValid() {
    179         if (mUri == null) {
    180             return false;
    181         }
    182         try {
    183             ParcelFileDescriptor pfd =
    184                     mContentResolver.openFileDescriptor(mUri, "r");
    185             if (pfd == null) {
    186                 Log.e(TAG, "Fail to open URI.");
    187                 return false;
    188             }
    189             pfd.close();
    190         } catch (IOException ex) {
    191             return false;
    192         }
    193         return true;
    194     }
    195 }
    196