UriImage.java revision 8eed706474910ccb978acda03e85d3261037da6e
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.util.Config;
34import android.util.Log;
35
36import java.io.ByteArrayOutputStream;
37import java.io.FileNotFoundException;
38import java.io.IOException;
39import java.io.InputStream;
40
41public class UriImage {
42    private static final String TAG = "UriImage";
43    private static final boolean DEBUG = true;
44    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
45
46    private final Context mContext;
47    private final Uri mUri;
48    private String mContentType;
49    private String mSrc;
50    private int mWidth;
51    private int mHeight;
52
53    public UriImage(Context context, Uri uri) {
54        if ((null == context) || (null == uri)) {
55            throw new IllegalArgumentException();
56        }
57
58        mContext = context;
59        mUri = uri;
60
61        Cursor c = SqliteWrapper.query(context, context.getContentResolver(),
62                            uri, null, null, null, null);
63
64        if (c == null) {
65            throw new IllegalArgumentException(
66                    "Query on " + uri + " returns null result.");
67        }
68
69        if ((c.getCount() != 1) || !c.moveToFirst()) {
70            c.close();
71            throw new IllegalArgumentException(
72                    "Query on " + uri + " returns 0 or multiple rows.");
73        }
74
75        try {
76            String filePath;
77            if (ImageModel.isMmsUri(uri)) {
78                filePath = c.getString(
79                        c.getColumnIndexOrThrow(Part._DATA));
80                mContentType = c.getString(
81                        c.getColumnIndexOrThrow(Part.CONTENT_TYPE));
82            } else {
83                filePath = c.getString(
84                        c.getColumnIndexOrThrow(Images.Media.DATA));
85                mContentType = c.getString(
86                        c.getColumnIndexOrThrow(Images.Media.MIME_TYPE));
87            }
88            mSrc = filePath.substring(filePath.lastIndexOf('/') + 1);
89            decodeBoundsInfo();
90        } finally {
91            c.close();
92        }
93    }
94
95    private void decodeBoundsInfo() {
96        InputStream input = null;
97        try {
98            input = mContext.getContentResolver().openInputStream(mUri);
99            BitmapFactory.Options opt = new BitmapFactory.Options();
100            opt.inJustDecodeBounds = true;
101            BitmapFactory.decodeStream(input, null, opt);
102            mWidth = opt.outWidth;
103            mHeight = opt.outHeight;
104        } catch (FileNotFoundException e) {
105            // Ignore
106            Log.e(TAG, "IOException caught while opening stream", e);
107        } finally {
108            if (null != input) {
109                try {
110                    input.close();
111                } catch (IOException e) {
112                    // Ignore
113                    Log.e(TAG, "IOException caught while closing stream", e);
114                }
115            }
116        }
117    }
118
119    public String getContentType() {
120        return mContentType;
121    }
122
123    public String getSrc() {
124        return mSrc;
125    }
126
127    public int getWidth() {
128        return mWidth;
129    }
130
131    public int getHeight() {
132        return mHeight;
133    }
134
135    public PduPart getResizedImageAsPart(int widthLimit, int heightLimit) {
136        PduPart part = new PduPart();
137
138        part.setContentType(getContentType().getBytes());
139        String src = getSrc();
140        part.setContentLocation(src.getBytes());
141        part.setContentId(src.substring(0, src.lastIndexOf(".")).getBytes());
142        byte[] data = getResizedImageData(widthLimit, heightLimit);
143        part.setData(data);
144
145        return part;
146    }
147
148    private byte[] getResizedImageData(int widthLimit, int heightLimit) {
149        int outWidth = mWidth;
150        int outHeight = mHeight;
151
152        int s = 1;
153        while ((outWidth / s > widthLimit) || (outHeight / s > heightLimit)) {
154            s *= 2;
155        }
156        if (LOCAL_LOGV) {
157            Log.v(TAG, "outWidth=" + outWidth / s
158                    + " outHeight=" + outHeight / s);
159        }
160        BitmapFactory.Options options = new BitmapFactory.Options();
161        options.inSampleSize = s;
162
163        InputStream input = null;
164        try {
165            input = mContext.getContentResolver().openInputStream(mUri);
166            Bitmap b = BitmapFactory.decodeStream(input, null, options);
167            ByteArrayOutputStream os = new ByteArrayOutputStream();
168            b.compress(CompressFormat.JPEG, MmsConfig.IMAGE_COMPRESSION_QUALITY, os);
169            return os.toByteArray();
170        } catch (FileNotFoundException e) {
171            Log.e(TAG, e.getMessage(), e);
172            return null;
173        } finally {
174            if (input != null) {
175                try {
176                    input.close();
177                } catch (IOException e) {
178                    Log.e(TAG, e.getMessage(), e);
179                }
180            }
181        }
182    }
183}
184