Util.java revision 2b82c4a17abfe926dc2942a6d1bf7982b006de6d
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
17package com.android.camera;
18
19import android.graphics.Bitmap;
20import android.graphics.BitmapFactory;
21import android.graphics.Matrix;
22import android.media.MediaMetadataRetriever;
23import android.os.ParcelFileDescriptor;
24import android.util.Log;
25
26
27import java.io.ByteArrayOutputStream;
28import java.io.Closeable;
29
30/**
31 * Collection of utility functions used in this package.
32 */
33public class Util {
34    private static final boolean VERBOSE = false;
35    private static final String TAG = "db.Util";
36
37    private Util() {
38    }
39
40    // Rotates the bitmap by the specified degree.
41    // If a new bitmap is created, the original bitmap is recycled.
42    public static Bitmap rotate(Bitmap b, int degrees) {
43        if (degrees != 0 && b != null) {
44            Matrix m = new Matrix();
45            m.setRotate(degrees,
46                    (float) b.getWidth() / 2, (float) b.getHeight() / 2);
47            try {
48                Bitmap b2 = Bitmap.createBitmap(
49                        b, 0, 0, b.getWidth(), b.getHeight(), m, true);
50                if (b != b2) {
51                    b.recycle();
52                    b = b2;
53                }
54            } catch (OutOfMemoryError ex) {
55                // We have no memory to rotate. Return the original bitmap.
56            }
57        }
58        return b;
59    }
60
61    /*
62     * Compute the sample size as a function of the image size and the target.
63     * Scale the image down so that both the width and height are just above the
64     * target. If this means that one of the dimension goes from above the
65     * target to below the target (e.g. given a width of 480 and an image width
66     * of 600 but sample size of 2 -- i.e. new width 300 -- bump the sample size
67     * down by 1.
68     */
69    public static int computeSampleSize(
70            BitmapFactory.Options options, int target) {
71        int w = options.outWidth;
72        int h = options.outHeight;
73
74        int candidateW = w / target;
75        int candidateH = h / target;
76        int candidate = Math.max(candidateW, candidateH);
77
78        if (candidate == 0) return 1;
79
80        if (candidate > 1) {
81            if ((w > target) && (w / candidate) < target) candidate -= 1;
82        }
83
84        if (candidate > 1) {
85            if ((h > target) && (h / candidate) < target) candidate -= 1;
86        }
87
88        return candidate;
89    }
90
91    /**
92     * Creates a centered bitmap of the desired size. Recycles the input.
93     * @param source
94     */
95    public static Bitmap extractMiniThumb(
96            Bitmap source, int width, int height) {
97        return Util.extractMiniThumb(source, width, height, true);
98    }
99
100    public static Bitmap extractMiniThumb(
101            Bitmap source, int width, int height, boolean recycle) {
102        if (source == null) {
103            return null;
104        }
105
106        float scale;
107        if (source.getWidth() < source.getHeight()) {
108            scale = width / (float) source.getWidth();
109        } else {
110            scale = height / (float) source.getHeight();
111        }
112        Matrix matrix = new Matrix();
113        matrix.setScale(scale, scale);
114        Bitmap miniThumbnail = ImageLoader.transform(matrix, source,
115                width, height, false);
116
117        if (recycle && miniThumbnail != source) {
118            source.recycle();
119        }
120        return miniThumbnail;
121    }
122
123    /**
124     * Creates a byte[] for a given bitmap of the desired size. Recycles the
125     * input bitmap.
126     */
127    public static byte[] miniThumbData(Bitmap source) {
128        if (source == null) return null;
129
130        Bitmap miniThumbnail = extractMiniThumb(
131                source, ImageManager.MINI_THUMB_TARGET_SIZE,
132                ImageManager.MINI_THUMB_TARGET_SIZE);
133
134        ByteArrayOutputStream miniOutStream = new ByteArrayOutputStream();
135        miniThumbnail.compress(Bitmap.CompressFormat.JPEG, 75, miniOutStream);
136        miniThumbnail.recycle();
137
138        try {
139            miniOutStream.close();
140            byte [] data = miniOutStream.toByteArray();
141            return data;
142        } catch (java.io.IOException ex) {
143            Log.e(TAG, "got exception ex " + ex);
144        }
145        return null;
146    }
147
148    /**
149     * @return true if the mimetype is a video mimetype.
150     */
151    public static boolean isVideoMimeType(String mimeType) {
152        return mimeType.startsWith("video/");
153    }
154
155    /**
156     * Create a video thumbnail for a video. May return null if the video is
157     * corrupt.
158     *
159     * @param filePath
160     */
161    public static Bitmap createVideoThumbnail(String filePath) {
162        Bitmap bitmap = null;
163        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
164        try {
165            retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
166            retriever.setDataSource(filePath);
167            bitmap = retriever.captureFrame();
168        } catch (IllegalArgumentException ex) {
169            // Assume this is a corrupt video file
170        } catch (RuntimeException ex) {
171            // Assume this is a corrupt video file.
172        } finally {
173            try {
174                retriever.release();
175            } catch (RuntimeException ex) {
176                // Ignore failures while cleaning up.
177            }
178        }
179        return bitmap;
180    }
181
182    public static int indexOf(String [] array, String s) {
183        for (int i = 0; i < array.length; i++) {
184            if (array[i].equals(s)) {
185                return i;
186            }
187        }
188        return -1;
189    }
190
191    public static void closeSiliently(Closeable c) {
192        if (c == null) return;
193        try {
194            c.close();
195        } catch (Throwable t) {
196            // do nothing
197        }
198    }
199
200    public static void closeSiliently(ParcelFileDescriptor c) {
201        if (c == null) return;
202        try {
203            c.close();
204        } catch (Throwable t) {
205            // do nothing
206        }
207    }
208
209}
210