android 图片解码显示流程

问题来源

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 的显示处理,所以可以显示动画。

android 图片解码显示流程

时间: 2024-07-30 13:03:56

android 图片解码显示流程的相关文章

【STM32H7教程】第58章 STM32H7的硬件JPEG应用之图片解码显示

完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第58章       STM32H7的硬件JPEG应用之图片解码显示 本章节为大家讲解硬件JPEG的图片解码功能,实际项目用到的地方比较多,一方面通过硬件JPEG可以加速图片解码,另一方面是JPEG图片比较小. 58.1 初学者重要提示 58.2 硬件JPEG驱动设计 58.3 硬件JPEG驱动移植和使用 58.4 实验例程设计框架 58.5 实验例程说明(MDK)

android 图片自定义显示

最近遇到需求,需要显示展示较多的图片,于是自己写了一个例子,需求如下 实现原理,把复杂的分组处理,每一行为一条,代码比较简单,主要在于分组处理 代码:上传资源总是失败,csdn服务器太差了 我传到以下网站了 http://blog.chinaunix.net/uid-8210028-id-4651943.html

Android 图片缩略图显示

//通过openRawResource获取一个inputStream对象 InputStream inputStream = getResources().openRawResource(R.drawable.temp); //通过一个InputStream创建一个BitmapDrawable对象 BitmapDrawable drawable = new BitmapDrawable(inputStream); //通过BitmapDrawable对象获得Bitmap对象 Bitmap bit

Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/53939176 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每天都有文章更新. 在本系列的上一篇文章中,我们学习了Glide的基本用法,体验了这个图片加载框架的强大功能,以及它非常简便的API.还没有看过上一篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(一),Glide的基本用法 . 在多数情况下,我们想要在界面上加载并展示一

Android NDK使用libjpeg解析JPEG图片,并显示到SurfaceView上

SurfaceView大概是谷歌提供给开发者最吸引人的的组件了,原因是SurfaceView的界面刷新允许在非UI线程中更新,正因为此,很多频繁更新界面的应用,如视频播放器.游戏.动画效果总会基于SurfaceView及其子类进行开发. 而最近我正在研究的一个应用是关于处理图片并显示图片的应用,图片实在是内存杀手,而处理图片则运算量非常大,这些都是令人头疼的问题. 分析应用,并选择实现技术 1.处理图片运算量大,为了提高运算效率,选择使用C语言处理图片 2.需要的内存空间较大,为节约内存并提高效

Android中ImnageView 中如何让图片拉伸显示?

通过设置android:scaleType="fitXY"使得图片拉伸显示.补充:scaleType的属性有matrix(默认).center.centerCrop.centerInside.fitCenter.fitEnd.fitStart.fitXY.android:scaleType="center"保持原图的大小,显示在ImageView的中心.当原图的size大于ImageView的size,超过部分裁剪处理. android:scaleType=&quo

从代码分析Android-Universal-Image-Loader的图片加载、显示流程

从UNIVERSAL IMAGE LOADER. PART 3(四个DisplayImage重载方法详解)中,我们学习了Android-Universal-Image-Loader(以下简称UIL)中四个DisplayImage重载方法的使用,如果你还没有学习,最好先返回去看看,不然可能不理解这篇文章.在这篇文章中我们将主要探讨Android-Universal-Image-Loader的主要流程和这些流程相关的类的分析. 我们先了解一下UIL加载图片的流程(可以通过查看ImageLoader.

Android 获取并显示远程图片 Picasso框架的使用(一)

转载请注明出处:明桑Android 在Android开发中,常需要从远程获取图片并显示在客户端,当然我们可以使用原生HttpUrlConnection和AsyncTask等操作来完成,但并不推荐,因为这样不仅需要我们编写大量的代码,还需要处理缓存和下载管理等,最好自己封装成库或者采用第三方库: Picasso:A Powerful Image Downloading and Caching Library for Android 根据名字就知道它是跟什么相关了(Picasso:毕加索)它的基本操

Android 获取并显示远程图片 Picasso框架的使用(二)

转载请注明出处:明桑Android 在上篇文章中介绍了Picasso的基本用法,这篇文章作为以上的练习: 本文代码github地址:UsePicasso 实现效果:(动图请耐心加载) 需要的知识点 了解Picasso框架的使用:Android 获取并显示远程图片 Picasso框架的使用(一) 知道如何自定义GridView 我们需要编写两个布局文件:activity_gridview.xml activity_main.xml 以及ImageAdapter类.GridImageActivity