Util.java revision 937fc48b37fafe3ffc8f4b52bd9a171bbb4d3a37
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 if (VERBOSE) { 89 Log.v(TAG, "for w/h " + w + "/" + h + " returning " + candidate 90 + "(" + (w / candidate) + " / " + (h / candidate)); 91 } 92 93 return candidate; 94 } 95 96 /** 97 * Creates a centered bitmap of the desired size. Recycles the input. 98 * @param source 99 */ 100 public static Bitmap extractMiniThumb( 101 Bitmap source, int width, int height) { 102 return Util.extractMiniThumb(source, width, height, true); 103 } 104 105 public static Bitmap extractMiniThumb( 106 Bitmap source, int width, int height, boolean recycle) { 107 if (source == null) { 108 return null; 109 } 110 111 float scale; 112 if (source.getWidth() < source.getHeight()) { 113 scale = width / (float) source.getWidth(); 114 } else { 115 scale = height / (float) source.getHeight(); 116 } 117 Matrix matrix = new Matrix(); 118 matrix.setScale(scale, scale); 119 Bitmap miniThumbnail = ImageLoader.transform(matrix, source, 120 width, height, false); 121 122 if (recycle && miniThumbnail != source) { 123 source.recycle(); 124 } 125 return miniThumbnail; 126 } 127 128 /** 129 * Creates a byte[] for a given bitmap of the desired size. Recycles the 130 * input bitmap. 131 */ 132 public static byte[] miniThumbData(Bitmap source) { 133 if (source == null) return null; 134 135 Bitmap miniThumbnail = extractMiniThumb( 136 source, ImageManager.MINI_THUMB_TARGET_SIZE, 137 ImageManager.MINI_THUMB_TARGET_SIZE); 138 139 ByteArrayOutputStream miniOutStream = new ByteArrayOutputStream(); 140 miniThumbnail.compress(Bitmap.CompressFormat.JPEG, 75, miniOutStream); 141 miniThumbnail.recycle(); 142 143 try { 144 miniOutStream.close(); 145 byte [] data = miniOutStream.toByteArray(); 146 return data; 147 } catch (java.io.IOException ex) { 148 Log.e(TAG, "got exception ex " + ex); 149 } 150 return null; 151 } 152 153 /** 154 * @return true if the mimetype is a video mimetype. 155 */ 156 public static boolean isVideoMimeType(String mimeType) { 157 return mimeType.startsWith("video/"); 158 } 159 160 /** 161 * Create a video thumbnail for a video. May return null if the video is 162 * corrupt. 163 * 164 * @param filePath 165 */ 166 public static Bitmap createVideoThumbnail(String filePath) { 167 Bitmap bitmap = null; 168 MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 169 try { 170 retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); 171 retriever.setDataSource(filePath); 172 bitmap = retriever.captureFrame(); 173 } catch (IllegalArgumentException ex) { 174 // Assume this is a corrupt video file 175 } catch (RuntimeException ex) { 176 // Assume this is a corrupt video file. 177 } finally { 178 try { 179 retriever.release(); 180 } catch (RuntimeException ex) { 181 // Ignore failures while cleaning up. 182 } 183 } 184 return bitmap; 185 } 186 187 public static int indexOf(String [] array, String s) { 188 for (int i = 0; i < array.length; i++) { 189 if (array[i].equals(s)) { 190 return i; 191 } 192 } 193 return -1; 194 } 195 196 public static void closeSiliently(Closeable c) { 197 if (c == null) return; 198 try { 199 c.close(); 200 } catch (Throwable t) { 201 // do nothing 202 } 203 } 204 205 public static void closeSiliently(ParcelFileDescriptor c) { 206 if (c == null) return; 207 try { 208 c.close(); 209 } catch (Throwable t) { 210 // do nothing 211 } 212 } 213 214} 215