博客
关于我
Android 高清加载巨图方案 拒绝压缩图片
阅读量:217 次
发布时间:2019-02-28

本文共 2773 字,大约阅读时间需要 9 分钟。

如何高效加载并展示大图?

随着移动设备的普及,用户对展示高清图片的需求不断增加。然而,传统的图片加载方式往往面临内存溢出(OOM)或性能优化问题。对于需要显示高清大图的场景,如地图、历史画卷等,如何高效地加载和展示图片,是一个值得深入探讨的问题。本文将详细介绍解决方案,并提供实际代码示例。

加载图片的挑战

一般情况下,为了避免内存溢出,图片加载时会采取以下措施:

  • 图片压缩:根据显示区域对图片进行比例缩放。
  • 缓存机制:使用LruCache等技术限制内存占用。
  • 然而,对于某些特殊场景,例如需要展示非常大的图片(如地图、历史画卷等),直接加载原图会导致屏幕显示不全,且内存占用过高。此时,如何在不影响性能的前提下,实现高效的大图加载与展示,成为了一个关键问题。

    BitmapRegionDecoder的应用

    为了应对上述挑战,Android提供了BitmapRegionDecoder类,专门用于加载图片的特定矩形区域。这种方式可以在不占用过多内存的前提下,灵活地显示大图的不同区域。以下是BitmapRegionDecoder的基本使用方法:

    BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.RGB_565; // 设定内存优化配置
    Rect rect = new Rect(0, 0, width, height);
    Bitmap bitmap = bitmapRegionDecoder.decodeRegion(rect, options);
    imageView.setImageBitmap(bitmap);

    自定义大图显示控件

    为了实现大图的拖动查看功能,我们需要自定义一个控件。该控件的核心逻辑包括:

  • 图片加载:使用BitmapRegionDecoder加载指定区域的图片。
  • 手势检测:通过MoveGestureDetector检测用户拖动手势,动态调整显示区域。
  • 边界检查:确保显示区域不会超出图片边界。
  • 以下是自定义控件的代码实现:

    public class LargeImageView extends View {
    private BitmapRegionDecoder mDecoder;
    private int mImageWidth, mImageHeight;
    private Rect mRect;
    private MoveGestureDetector mDetector;
    public LargeImageView(Context context) {
    super(context);
    init();
    }
    private void init() {
    mDetector = new MoveGestureDetector(context, new SimpleMoveGestureDetector());
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    mDetector.onTouchEvent(event);
    return true;
    }
    @Override
    protected void onDraw(Canvas canvas) {
    Bitmap bitmap = mDecoder.decodeRegion(mRect, options);
    canvas.drawBitmap(bitmap, 0, 0, null);
    }
    }

    完整实现步骤

  • 设置图片流:通过setInputStream方法加载图片流,初始化BitmapRegionDecoder并获取图片尺寸。
  • public void setInputStream(InputStream is) {
    try {
    mDecoder = BitmapRegionDecoder.newInstance(is, false);
    BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
    tmpOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(is, null, tmpOptions);
    mImageWidth = tmpOptions.outWidth;
    mImageHeight = tmpOptions.outHeight;
    requestLayout();
    invalidate();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    1. 初始化手势检测:在布局初始化时创建MoveGestureDetector实例。
    2. public class MoveGestureDetector extends BaseGestureDetector {
      // ...手势检测逻辑...
      }
      1. 手势回调:定义一个简单的回调类,处理拖动事件。
      2. public class SimpleMoveGestureDetector implements OnMoveGestureListener {
        @Override
        public boolean onMove(MoveGestureDetector detector) {
        return false;
        }
        }
        1. 布局中的使用
        2. 测试与验证

          在实际应用中,需要通过测试确保控件正常工作,包括:

        3. 图片加载成功:检查图片是否正确显示在指定区域。
        4. 拖动功能:验证用户是否可以通过拖动手势查看不同区域。
        5. 边界适应:确保显示区域不会超出图片边界。
        6. 通过以上步骤,可以轻松实现大图的高效加载与展示,同时提供良好的用户体验。

    转载地址:http://nles.baihongyu.com/

    你可能感兴趣的文章
    NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
    查看>>
    NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
    查看>>
    NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
    查看>>
    NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
    查看>>
    NIH发布包含10600张CT图像数据库 为AI算法测试铺路
    查看>>
    Nim教程【十二】
    查看>>
    Nim游戏
    查看>>
    NIO ByteBuffer实现原理
    查看>>
    Nio ByteBuffer组件读写指针切换原理与常用方法
    查看>>
    NIO Selector实现原理
    查看>>
    nio 中channel和buffer的基本使用
    查看>>
    NIO基于UDP协议的网络编程
    查看>>
    NISP一级,NISP二级报考说明,零基础入门到精通,收藏这篇就够了
    查看>>
    Nitrux 3.8 发布!性能全面提升,带来非凡体验
    查看>>
    NI笔试——大数加法
    查看>>
    NLog 自定义字段 写入 oracle
    查看>>
    NLog类库使用探索——详解配置
    查看>>
    NLP 基于kashgari和BERT实现中文命名实体识别(NER)
    查看>>
    NLP 项目:维基百科文章爬虫和分类【01】 - 语料库阅读器
    查看>>
    NLP_什么是统计语言模型_条件概率的链式法则_n元统计语言模型_马尔科夫链_数据稀疏(出现了词库中没有的词)_统计语言模型的平滑策略---人工智能工作笔记0035
    查看>>