UriImage.java revision bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3
1/* 2 * Copyright (C) 2008 Esmertec AG. 3 * Copyright (C) 2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.mms.ui; 19 20import com.android.mms.MmsConfig; 21import com.android.mms.model.ImageModel; 22import com.google.android.mms.pdu.PduPart; 23import com.google.android.mms.util.SqliteWrapper; 24 25import android.content.Context; 26import android.database.Cursor; 27import android.graphics.Bitmap; 28import android.graphics.BitmapFactory; 29import android.graphics.Bitmap.CompressFormat; 30import android.net.Uri; 31import android.provider.MediaStore.Images; 32import android.provider.Telephony.Mms.Part; 33import android.text.TextUtils; 34import android.util.Config; 35import android.util.Log; 36import android.webkit.MimeTypeMap; 37 38import java.io.ByteArrayOutputStream; 39import java.io.FileNotFoundException; 40import java.io.IOException; 41import java.io.InputStream; 42 43public class UriImage { 44 private static final String TAG = "UriImage"; 45 private static final boolean DEBUG = true; 46 private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; 47 48 private final Context mContext; 49 private final Uri mUri; 50 private String mContentType; 51 private String mPath; 52 private String mSrc; 53 private int mWidth; 54 private int mHeight; 55 56 public UriImage(Context context, Uri uri) { 57 if ((null == context) || (null == uri)) { 58 throw new IllegalArgumentException(); 59 } 60 61 String scheme = uri.getScheme(); 62 if (scheme.equals("content")) { 63 initFromContentUri(context, uri); 64 } else if (uri.getScheme().equals("file")) { 65 initFromFile(context, uri); 66 } 67 68 mSrc = mPath.substring(mPath.lastIndexOf('/') + 1); 69 mContext = context; 70 mUri = uri; 71 72 decodeBoundsInfo(); 73 } 74 75 private void initFromFile(Context context, Uri uri) { 76 MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton(); 77 String extension = MimeTypeMap.getFileExtensionFromUrl(uri.toString()); 78 mContentType = mimeTypeMap.getMimeTypeFromExtension(extension); 79 if (mContentType == null) { 80 throw new IllegalArgumentException( 81 "Unable to determine extension for " + uri.toString()); 82 } 83 mPath = uri.getPath(); 84 } 85 86 private void initFromContentUri(Context context, Uri uri) { 87 Cursor c = SqliteWrapper.query(context, context.getContentResolver(), 88 uri, null, null, null, null); 89 90 if (c == null) { 91 throw new IllegalArgumentException( 92 "Query on " + uri + " returns null result."); 93 } 94 95 try { 96 if ((c.getCount() != 1) || !c.moveToFirst()) { 97 throw new IllegalArgumentException( 98 "Query on " + uri + " returns 0 or multiple rows."); 99 } 100 101 String filePath; 102 if (ImageModel.isMmsUri(uri)) { 103 filePath = c.getString(c.getColumnIndexOrThrow(Part.FILENAME)); 104 if (TextUtils.isEmpty(filePath)) { 105 filePath = c.getString( 106 c.getColumnIndexOrThrow(Part._DATA)); 107 } 108 mContentType = c.getString( 109 c.getColumnIndexOrThrow(Part.CONTENT_TYPE)); 110 } else { 111 filePath = c.getString( 112 c.getColumnIndexOrThrow(Images.Media.DATA)); 113 mContentType = c.getString( 114 c.getColumnIndexOrThrow(Images.Media.MIME_TYPE)); 115 } 116 mPath = filePath; 117 } finally { 118 c.close(); 119 } 120 } 121 122 private void decodeBoundsInfo() { 123 InputStream input = null; 124 try { 125 input = mContext.getContentResolver().openInputStream(mUri); 126 BitmapFactory.Options opt = new BitmapFactory.Options(); 127 opt.inJustDecodeBounds = true; 128 BitmapFactory.decodeStream(input, null, opt); 129 mWidth = opt.outWidth; 130 mHeight = opt.outHeight; 131 } catch (FileNotFoundException e) { 132 // Ignore 133 Log.e(TAG, "IOException caught while opening stream", e); 134 } finally { 135 if (null != input) { 136 try { 137 input.close(); 138 } catch (IOException e) { 139 // Ignore 140 Log.e(TAG, "IOException caught while closing stream", e); 141 } 142 } 143 } 144 } 145 146 public String getContentType() { 147 return mContentType; 148 } 149 150 public String getSrc() { 151 return mSrc; 152 } 153 154 public int getWidth() { 155 return mWidth; 156 } 157 158 public int getHeight() { 159 return mHeight; 160 } 161 162 public PduPart getResizedImageAsPart(int widthLimit, int heightLimit) { 163 PduPart part = new PduPart(); 164 165 byte[] data = getResizedImageData(widthLimit, heightLimit); 166 if (data == null) { 167 if (LOCAL_LOGV) { 168 Log.v(TAG, "Resize image failed."); 169 } 170 return null; 171 } 172 173 part.setData(data); 174 part.setContentType(getContentType().getBytes()); 175 String src = getSrc(); 176 byte[] srcBytes = src.getBytes(); 177 part.setContentLocation(srcBytes); 178 part.setFilename(srcBytes); 179 part.setContentId(src.substring(0, src.lastIndexOf(".")).getBytes()); 180 181 return part; 182 } 183 184 private byte[] getResizedImageData(int widthLimit, int heightLimit) { 185 int outWidth = mWidth; 186 int outHeight = mHeight; 187 188 int s = 1; 189 while ((outWidth / s > widthLimit) || (outHeight / s > heightLimit)) { 190 s *= 2; 191 } 192 if (LOCAL_LOGV) { 193 Log.v(TAG, "outWidth=" + outWidth / s 194 + " outHeight=" + outHeight / s); 195 } 196 BitmapFactory.Options options = new BitmapFactory.Options(); 197 options.inSampleSize = s; 198 199 InputStream input = null; 200 try { 201 input = mContext.getContentResolver().openInputStream(mUri); 202 Bitmap b = BitmapFactory.decodeStream(input, null, options); 203 if (b == null) { 204 return null; 205 } 206 207 ByteArrayOutputStream os = new ByteArrayOutputStream(); 208 b.compress(CompressFormat.JPEG, MessageUtils.IMAGE_COMPRESSION_QUALITY, os); 209 return os.toByteArray(); 210 } catch (FileNotFoundException e) { 211 Log.e(TAG, e.getMessage(), e); 212 return null; 213 } finally { 214 if (input != null) { 215 try { 216 input.close(); 217 } catch (IOException e) { 218 Log.e(TAG, e.getMessage(), e); 219 } 220 } 221 } 222 } 223} 224