现在的位置: 首页 > 综合 > 正文

Android: MediaScanner生成thumbnail的算法

2013年04月21日 ⁄ 综合 ⁄ 共 2554字 ⁄ 字号 评论关闭

/**
* Check if the corresponding thumbnail and mini-thumb have been created
* for the given uri. This method creates both of them if they do not
* exist yet or have been changed since last check. After thumbnails are
* created, MINI_KIND thumbnail is stored in JPEG file and MICRO_KIND
* thumbnail is stored in a random access file (MiniThumbFile).
*
* @throws IOException
*/
void execute() throws IOException {
MiniThumbFile miniThumbFile = MiniThumbFile.instance(mUri);
long magic = mMagic;
if (magic != 0) {
long fileMagic = miniThumbFile.getMagic(mOrigId);
if (fileMagic == magic) {
Cursor c = null;
ParcelFileDescriptor pfd = null;
try {
c = mCr.query(mThumbUri, THUMB_PROJECTION,
mOrigColumnName + " = " + mOrigId, null, null);
if (c != null && c.moveToFirst()) {
pfd = mCr.openFileDescriptor(
mThumbUri.buildUpon().appendPath(c.getString(0)).build(), "r");
}
} catch (IOException ex) {
// MINI_THUMBNAIL not exists, ignore the exception and generate one.
} finally {
if (c != null) c.close();
if (pfd != null) {
pfd.close();
return;
}
}
}
}
// If we can't retrieve the thumbnail, first check if there is one
// embedded in the EXIF data. If not, or it's not big enough,
// decompress the full size image.
Bitmap bitmap = null;
if (mPath != null) {
if (mIsVideo) {
bitmap = ThumbnailUtils.createVideoThumbnail(mPath,
Video.Thumbnails.MINI_KIND);
} else {
bitmap = ThumbnailUtils.createImageThumbnail(mPath,
Images.Thumbnails.MINI_KIND);
}
if (bitmap == null) {
Log.w(TAG, "Can't create mini thumbnail for " + mPath);
return;
}
Uri uri = updateDatabase(bitmap);
if (uri != null) {
OutputStream thumbOut = mCr.openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, thumbOut);
thumbOut.close();
}
}
bitmap = ThumbnailUtils.extractThumbnail(bitmap,
ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
ThumbnailUtils.TARGET_SIZE_MICRO_THUMBNAIL,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
if (bitmap != null) {
ByteArrayOutputStream miniOutStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 75, miniOutStream);
bitmap.recycle();
byte [] data = null;
try {
miniOutStream.close();
data = miniOutStream.toByteArray();
} catch (java.io.IOException ex) {
Log.e(TAG, "got exception ex " + ex);
}
// We may consider retire this proprietary format, after all it's size is only
// 128 x 128 at most, which is still reasonable to be stored in database.
// Gallery application can use the MINI_THUMB_MAGIC value to determine if it's
// time to query and fetch by using Cursor.getBlob
if (data != null) {
// make a new magic number since things are out of sync
do {
magic = mRandom.nextLong();
} while (magic == 0);
miniThumbFile.saveMiniThumbToFile(data, mOrigId, magic);
ContentValues values = new ContentValues();
// both video/images table use the same column name "mini_thumb_magic"
values.put(ImageColumns.MINI_THUMB_MAGIC, magic);
mCr.update(mUri, values, null, null);
}
} else {
Log.w(TAG, "can't create bitmap for thumbnail.");
}
}

抱歉!评论已关闭.