android 圖片解碼顯示流程

來源:互聯網
上載者:User

標籤:圖片   動畫   bitmap   uri   

問題來源android 可以在 gallery 裡面顯示內部儲存的圖片,支援 jpeg,png,gif,bmp 等,甚至檔案類型和圖片尾碼名不一致,只要是圖片檔案就能顯示,然後 git 只會顯示第一幀映像,然而 android 其實是可以顯示 gif 動畫的,在瀏覽器裡開啟 gif 動畫,就能夠正常載入顯示。
Gallery 查看圖片gallery 實現了 Gallery/src/com/android/camera/ViewImage.java   
                        ImageViewTouchBase newView =                                mSlideShowImageViews[mSlideShowImageCurrent];                        newView.setVisibility(View.VISIBLE);                        newView.setImageRotateBitmapResetBase(bitmap, true);                        newView.bringToFront();

通過自己實現的  ImageViewTouchBase 裝載圖片並顯示
ImageViewTouchBase 繼承自 framework 的 ImageView
package com.android.camera;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Matrix;import android.graphics.RectF;import android.graphics.drawable.Drawable;import android.os.Handler;import android.util.AttributeSet;import android.view.KeyEvent;import android.widget.ImageView;abstract class ImageViewTouchBase extends ImageView {

framework 處理圖片ImageView 是 android 圖片框架實現通用圖片處理顯示類:可以顯示 resource 裡面的圖片,
    public void setImageResource(int resId) {        if (mUri != null || mResource != resId) {            updateDrawable(null);            mResource = resId;            mUri = null;            final int oldWidth = mDrawableWidth;            final int oldHeight = mDrawableHeight;            resolveUri();            if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {                requestLayout();            }            invalidate();        }    }

我們在 gallery 裡面開啟的圖片調用是通過 uri 傳過來的,
    public void setImageURI(Uri uri) {        if (mResource != 0 ||                (mUri != uri &&                 (uri == null || mUri == null || !uri.equals(mUri)))) {            updateDrawable(null);            mResource = 0;            mUri = uri;            final int oldWidth = mDrawableWidth;            final int oldHeight = mDrawableHeight;            resolveUri();            if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {                requestLayout();            }            invalidate();        }    }

android 會解析 uri 得到目標檔案路徑
        } else if (mUri != null) {            String scheme = mUri.getScheme();            if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {                try {                    // Load drawable through Resources, to get the source density information                    ContentResolver.OpenResourceIdResult r =                            mContext.getContentResolver().getResourceId(mUri);                    d = r.r.getDrawable(r.id);                } catch (Exception e) {                    Log.w("ImageView", "Unable to open content: " + mUri, e);                }            } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)                    || ContentResolver.SCHEME_FILE.equals(scheme)) {                InputStream stream = null;                try {                    stream = mContext.getContentResolver().openInputStream(mUri);                    d = Drawable.createFromStream(stream, null);                } catch (Exception e) {                    Log.w("ImageView", "Unable to open content: " + mUri, e);                } finally {                    if (stream != null) {                        try {                            stream.close();                        } catch (IOException e) {                            Log.w("ImageView", "Unable to close content: " + mUri, e);                        }                    }                }        } else {                d = Drawable.createFromPath(mUri.toString());            }

我們點擊 gallery 的圖片會產生包含 content 的 uri:I/ActivityManager( 1304): START u0 {dat= content://media/external/images/media/21 cmp=com.android.gallery/com.android.camera.ViewImage (has extras)} from pid 1706

然後通過 Drawable 從 inputstream 裡面解析建立 Drawable 對象
    public static Drawable createFromStream(InputStream is, String srcName) {        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, srcName != null ? srcName : "Unknown drawable");        try {            return createFromResourceStream(null, null, is, srcName, null);        } finally {            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);        }    }

後面的流程就是交給 skia 解析然後獲得一個 bitmap 並返回了。 skia 的 decode 可以自動識別 steam 裡面的資料流建立相應的 decoder。問題答案framework 是通用的圖片顯示處理,最後只返回了一個 bitmap ,所以 gif 只能處理第一幀映像了,但是 browser 是從新實現了映像顯示介面,有專門針對 gif 的顯示處理,所以可以顯示動畫。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.