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