16a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang/* 26a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * Copyright (C) 2010 The Android Open Source Project 36a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * 46a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * Licensed under the Apache License, Version 2.0 (the "License"); 56a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * you may not use this file except in compliance with the License. 66a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * You may obtain a copy of the License at 76a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * 86a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * http://www.apache.org/licenses/LICENSE-2.0 96a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * 106a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * Unless required by applicable law or agreed to in writing, software 116a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * distributed under the License is distributed on an "AS IS" BASIS, 126a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * See the License for the specific language governing permissions and 146a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * limitations under the License. 156a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang */ 166a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 176a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangpackage com.android.gallery3d.photoeditor; 186a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 196a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.content.Context; 206a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.database.Cursor; 216a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.graphics.Bitmap; 226a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.graphics.Bitmap.CompressFormat; 236a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.graphics.BitmapFactory; 246a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.graphics.Canvas; 256a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.graphics.Matrix; 266a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.graphics.Paint; 276a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.graphics.Rect; 286a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.graphics.RectF; 296a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.net.Uri; 306a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.provider.MediaStore.Images.ImageColumns; 316a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport android.util.Log; 326a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 336a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport java.io.Closeable; 346a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport java.io.File; 356a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport java.io.FileNotFoundException; 366a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport java.io.FileOutputStream; 376a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport java.io.IOException; 386a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport java.io.InputStream; 396a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangimport java.io.OutputStream; 406a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 416a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang/** 426a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * Utils for bitmap operations. 436a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang */ 446a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huangpublic class BitmapUtils { 456a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 466a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang private static final String TAG = "BitmapUtils"; 476a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang private static final int DEFAULT_COMPRESS_QUALITY = 90; 486a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang private static final int INDEX_ORIENTATION = 0; 496a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 506a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang private static final String[] IMAGE_PROJECTION = new String[] { 516a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang ImageColumns.ORIENTATION 526a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang }; 536a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 546a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang private final Context context; 556a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 566a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang public BitmapUtils(Context context) { 576a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang this.context = context; 586a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 596a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 606a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang /** 616a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * Creates a mutable bitmap from subset of source bitmap, transformed by the optional matrix. 626a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang */ 63f66bd12b33e0d590e192a3551e9affc55eef9a48Yuli Huang private static Bitmap createBitmap( 646a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Bitmap source, int x, int y, int width, int height, Matrix m) { 656a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang // Re-implement Bitmap createBitmap() to always return a mutable bitmap. 666a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Canvas canvas = new Canvas(); 676a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 686a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Bitmap bitmap; 696a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Paint paint; 706a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if ((m == null) || m.isIdentity()) { 716a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bitmap = Bitmap.createBitmap(width, height, source.getConfig()); 726a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang paint = null; 736a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } else { 746a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang RectF rect = new RectF(0, 0, width, height); 756a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang m.mapRect(rect); 766a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bitmap = Bitmap.createBitmap( 776a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Math.round(rect.width()), Math.round(rect.height()), source.getConfig()); 786a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 796a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang canvas.translate(-rect.left, -rect.top); 806a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang canvas.concat(m); 816a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 826a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang paint = new Paint(Paint.FILTER_BITMAP_FLAG); 836a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if (!m.rectStaysRect()) { 846a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang paint.setAntiAlias(true); 856a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 866a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 876a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bitmap.setDensity(source.getDensity()); 886a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang canvas.setBitmap(bitmap); 896a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 906a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Rect srcBounds = new Rect(x, y, x + width, y + height); 916a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang RectF dstBounds = new RectF(0, 0, width, height); 926a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang canvas.drawBitmap(source, srcBounds, dstBounds, paint); 936a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang return bitmap; 946a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 956a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 966a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang private void closeStream(Closeable stream) { 976a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if (stream != null) { 986a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang try { 996a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang stream.close(); 1006a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } catch (IOException e) { 1016a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang e.printStackTrace(); 1026a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1036a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1046a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1056a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1066a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang private Rect getBitmapBounds(Uri uri) { 1076a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Rect bounds = new Rect(); 1086a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang InputStream is = null; 1096a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1106a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang try { 1116a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang is = context.getContentResolver().openInputStream(uri); 1126a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang BitmapFactory.Options options = new BitmapFactory.Options(); 1136a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang options.inJustDecodeBounds = true; 1146a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang BitmapFactory.decodeStream(is, null, options); 1156a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1166a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bounds.right = options.outWidth; 1176a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bounds.bottom = options.outHeight; 1186a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } catch (FileNotFoundException e) { 1196a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang e.printStackTrace(); 1206a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } finally { 1216a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang closeStream(is); 1226a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1236a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1246a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang return bounds; 1256a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1266a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1276a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang private int getOrientation(Uri uri) { 1286a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang int orientation = 0; 129fef5b9860f0a88fc673af2187938956ebd0ade75Yuli Huang Cursor cursor = null; 1306a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang try { 131fef5b9860f0a88fc673af2187938956ebd0ade75Yuli Huang cursor = context.getContentResolver().query(uri, IMAGE_PROJECTION, null, null, null); 1326a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if ((cursor != null) && cursor.moveToNext()) { 1336a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang orientation = cursor.getInt(INDEX_ORIENTATION); 1346a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 135fef5b9860f0a88fc673af2187938956ebd0ade75Yuli Huang } catch (Exception e) { 136fef5b9860f0a88fc673af2187938956ebd0ade75Yuli Huang // Ignore error for no orientation column; just use the default orientation value 0. 1376a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } finally { 1386a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if (cursor != null) { 1396a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang cursor.close(); 1406a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1416a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1426a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang return orientation; 1436a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1446a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1456a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang /** 1466a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * Decodes bitmap (maybe immutable) that keeps aspect-ratio and spans most within the bounds. 1476a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang */ 1486a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang private Bitmap decodeBitmap(Uri uri, int width, int height) { 1496a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang InputStream is = null; 1506a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Bitmap bitmap = null; 1516a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1526a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang try { 1536a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang // TODO: Take max pixels allowed into account for calculation to avoid possible OOM. 1546a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Rect bounds = getBitmapBounds(uri); 1556a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang int sampleSize = Math.max(bounds.width() / width, bounds.height() / height); 1566a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang sampleSize = Math.min(sampleSize, 1576a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Math.max(bounds.width() / height, bounds.height() / width)); 1586a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1596a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang BitmapFactory.Options options = new BitmapFactory.Options(); 1606a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang options.inSampleSize = Math.max(sampleSize, 1); 1616a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang options.inPreferredConfig = Bitmap.Config.ARGB_8888; 1626a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1636a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang is = context.getContentResolver().openInputStream(uri); 1646a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bitmap = BitmapFactory.decodeStream(is, null, options); 1656a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } catch (FileNotFoundException e) { 1666a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Log.e(TAG, "FileNotFoundException: " + uri); 1676a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } finally { 1686a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang closeStream(is); 1696a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1706a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 171f66bd12b33e0d590e192a3551e9affc55eef9a48Yuli Huang // Ensure bitmap in 8888 format, good for editing as well as GL compatible. 172f66bd12b33e0d590e192a3551e9affc55eef9a48Yuli Huang if ((bitmap != null) && (bitmap.getConfig() != Bitmap.Config.ARGB_8888)) { 173f66bd12b33e0d590e192a3551e9affc55eef9a48Yuli Huang Bitmap copy = bitmap.copy(Bitmap.Config.ARGB_8888, true); 174f66bd12b33e0d590e192a3551e9affc55eef9a48Yuli Huang bitmap.recycle(); 175f66bd12b33e0d590e192a3551e9affc55eef9a48Yuli Huang bitmap = copy; 176f66bd12b33e0d590e192a3551e9affc55eef9a48Yuli Huang } 177f66bd12b33e0d590e192a3551e9affc55eef9a48Yuli Huang 1786a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if (bitmap != null) { 179f66bd12b33e0d590e192a3551e9affc55eef9a48Yuli Huang // Scale down the sampled bitmap if it's still larger than the desired dimension. 1806a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang float scale = Math.min((float) width / bitmap.getWidth(), 1816a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang (float) height / bitmap.getHeight()); 1826a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang scale = Math.max(scale, Math.min((float) height / bitmap.getWidth(), 1836a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang (float) width / bitmap.getHeight())); 1846a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if (scale < 1) { 1856a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Matrix m = new Matrix(); 1866a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang m.setScale(scale, scale); 1876a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Bitmap transformed = createBitmap( 1886a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m); 1896a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bitmap.recycle(); 1906a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang return transformed; 1916a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1926a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1936a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang return bitmap; 1946a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 1956a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 1966a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang /** 1976a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * Gets decoded bitmap that keeps orientation as well. 1986a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang */ 1996a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang public Bitmap getBitmap(Uri uri, int width, int height) { 2006a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Bitmap bitmap = decodeBitmap(uri, width, height); 2016a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 2026a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang // Rotate the decoded bitmap according to its orientation if it's necessary. 2036a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if (bitmap != null) { 2046a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang int orientation = getOrientation(uri); 2056a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if (orientation != 0) { 2066a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Matrix m = new Matrix(); 2076a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang m.setRotate(orientation); 2086a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Bitmap transformed = createBitmap( 2096a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m); 2106a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bitmap.recycle(); 2116a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang return transformed; 2126a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 2136a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 2146a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang return bitmap; 2156a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 2166a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 2176a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang /** 2186a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * Saves the bitmap by given directory, filename, and format; if the directory is given null, 2196a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang * then saves it under the cache directory. 2206a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang */ 2216a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang public File saveBitmap( 2226a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang Bitmap bitmap, String directory, String filename, CompressFormat format) { 2236a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 2246a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if (directory == null) { 2256a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang directory = context.getCacheDir().getAbsolutePath(); 2266a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } else { 2276a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang // Check if the given directory exists or try to create it. 2286a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang File file = new File(directory); 2296a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang if (!file.isDirectory() && !file.mkdirs()) { 2306a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang return null; 2316a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 2326a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 2336a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 2346a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang File file = null; 2356a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang OutputStream os = null; 2366a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang 2376a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang try { 2386a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang filename = (format == CompressFormat.PNG) ? filename + ".png" : filename + ".jpg"; 2396a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang file = new File(directory, filename); 2406a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang os = new FileOutputStream(file); 2416a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang bitmap.compress(format, DEFAULT_COMPRESS_QUALITY, os); 2426a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } catch (FileNotFoundException e) { 2436a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang e.printStackTrace(); 2446a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } finally { 2456a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang closeStream(os); 2466a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 2476a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang return file; 2486a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang } 2496a12ad70df5da5052a8381e2cdda79e6a314cee9Yuli Huang} 250