0
回答
Android: MediaScanner生成thumbnail的算法

/**
     * 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.");
        }
    }
 


原文链接:http://blog.csdn.net/zmyde2010/article/details/6038799
<无标签>
举报
长平狐
发帖于6年前 0回/1K+阅
顶部