Android 加载高清巨图,无需剪裁压缩

2023-11-05

LargeImage

Android 加载大图 可以高清显示10000*10000像素的图片
可以滑动,放大缩小具有PhotoView的效果
普通图片也可以用它展示 #Gradle

 compile 'com.shizhefei:LargeImageView:1.0.9'

Download Demo apk

#效果

image

#使用方法

<com.shizhefei.view.largeimage.LargeImageView
    android:id="@+id/imageView"
    android:scrollbars="vertical|horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

代码

largeImageView = (LargeImageView) findViewById(R.id.imageView);

//通过文件的方式加载sd卡中的大图
largeImageView.setImage(new FileBitmapDecoderFactory(file));

//通过流的方式加载assets文件夹里面的大图
largeImageView.setImage(new InputStreamBitmapDecoderFactory(getAssets().open(ss[position])))

//加载普通大小图片
largeImageView.setImage(R.drawable.cat);
largeImageView.setImage(drawable);
largeImageView.setImage(bitmap);

支持的事件

    largeImageView.setOnClickListener(onClickListener);
    largeImageView.setOnLongClickListener(onLongClickListener);

设置是否可以缩放

 largeImageView.setEnabled(true);

Hook临界值(不设置的话会使用默认的计算缩放最小倍数和最大倍数)

/**
 * Hook临界值
 */
public interface CriticalScaleValueHook {

    /**
     * 返回最小的缩放倍数
     * scale为1的话表示,显示的图片和View一样宽
     *
     * @param largeImageView
     * @param imageWidth
     * @param imageHeight
     * @param suggestMinScale 默认建议的最小的缩放倍数
     * @return
     */
    float getMinScale(LargeImageView largeImageView, int imageWidth, int imageHeight, float suggestMinScale);

    /**
     * 返回最大的缩放倍数
     * scale为1的话表示,显示的图片和View一样宽
     *
     * @param largeImageView
     * @param imageWidth
     * @param imageHeight
     * @param suggestMaxScale 默认建议的最大的缩放倍数
     * @return
     */
    float getMaxScale(LargeImageView largeImageView, int imageWidth, int imageHeight, float suggestMaxScale);

}

例如

   largeImageView.setCriticalScaleValueHook(new LargeImageView.CriticalScaleValueHook() {
        @Override
        public float getMinScale(LargeImageView largeImageView, int imageWidth, int imageHeight, float suggestMinScale) {
            return 1;
        }

        @Override
        public float getMaxScale(LargeImageView largeImageView, int imageWidth, int imageHeight, float suggestMaxScale) {
            return 4;
        }
    });

加载网络的图片,先下载本地,再通过加载图片的文件
比如glide加载图片,具体代码查看demo

    String url = "http://img.tuku.cn/file_big/201502/3d101a2e6cbd43bc8f395750052c8785.jpg";
    Glide.with(this).load(url).downloadOnly(new ProgressTarget<String, File>(url, null) {
        @Override
        public void onLoadStarted(Drawable placeholder) {
            super.onLoadStarted(placeholder);
            ringProgressBar.setVisibility(View.VISIBLE);
            ringProgressBar.setProgress(0);
        }

        @Override
        public void onProgress(long bytesRead, long expectedLength) {
            int p = 0;
            if (expectedLength >= 0) {
                p = (int) (100 * bytesRead / expectedLength);
            }
            ringProgressBar.setProgress(p);
        }

        @Override
        public void onResourceReady(File resource, GlideAnimation<? super File> animation) {
            super.onResourceReady(resource, animation);
            ringProgressBar.setVisibility(View.GONE);
            largeImageView.setImage(new FileBitmapDecoderFactory(resource));
        }

        @Override
        public void getSize(SizeReadyCallback cb) {
            cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
        }
    });

#实现原理

只加载显示的区域的图片,切成小块拼接.

#LargeImageView 根据滚动和缩放事件 scrollTo 对应的位置,计算当前显示区域的图片绘制出来

#UpdateImageView 监听View的显示区域的变化,然后加载显示区域内应该显示的图片区域,然后绘制到View上
UpdateView负责监听显示区域的变化的View,子类通过重写onUpdateWindow(Rect visiableRect)监听显示区域,大部分代码源于SurfaceView监听代码

###BlockImageLoader负责加载显示区域的图片块。 ###

###实现细节: ### 每次LargeImageView的onDraw方法都会调用ImageManagerd的getDrawData(float imageScale, Rect imageRect)方法,imageRect为在View上图片显示的区域(需要加载的图片区域),imageScale 假设等于4的话,就是View上显示1像素,image要加载4个像素的区域(缩小4倍的图片)
getDrawData(float imageScale, Rect imageRect)实现细节:
手势移动,图片显示区域会变化。比如显示区域是800800,向右移动2像素,难道要重新加载800800的图片区域? 所以我采用了图片切块的操作,分块的优化

  1. 比如图片显示比例是1,那么要横向分多少份才,纵向分多少分,才合理?图片显示比例是4,横向分多少份才,纵向分多少分,才合理。

所以我采用了基准块(图片比例是1,一个图片块的宽高的合理sise) BASE_BLOCKSIZE = context.getResources().getDisplayMetrics().heightPixels / 2+1;
图片缩放比例为1的话,图片块宽高是BASE_BLOCKSIZE
图片缩放比例为4的话,图片块宽高是4*BASE_BLOCKSIZE
图片没被位移,那么屏幕上显示横向2列,纵向getDisplayMetrics().heightPixels/BASE_BLOCKSIZE行

2.因为手势放大缩小操作要加载不同清晰度的图片区域,比如之前的图片缩放是4,现在缩放是4.2,难道要重新加载?

通过public int getNearScale(float imageScale)方法计算趋于2的指数次方的值(1,2,4,8,16)
比如3.9和4.2和4比较接近,就直接加载图片显示比例为4的图片块

3.之前没加载的区域,难道要空白显示么?

为了避免加载出现白色块,我会缓存当前比例的加载的图片块,以及2倍比例的图片块(之前加载过,并且当前还属于当前显示区域的,如果不是的话也不缓存它) 所以发现没有的话去拿其他比例的图片区去显示

4.难道只加载显示区域?

当然,还会去加载旁边一部分没显示的区域的图片块

5.onDraw方法是UI线程,调用getDrawData(float imageScale, Rect imageRect)加载图片块的方法怎么不卡住

getDrawData只返回之前加载过的图片块,而没有加载的是通过LoadHandler.sendMessage去加载 LoadHandler的Loop是通过HandlerThread线程创建的Loop,也就是开个线程加载.

每加载一个图片块通过 onImageLoadListenner.onBlockImageLoadFinished();onDraw重绘

onDraw又调用getDrawData加载,直至需要显示的图片块加载完成


转自:https://github.com/LuckyJayce/LargeImage

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 加载高清巨图,无需剪裁压缩 的相关文章

随机推荐

  • Android之使用本地缓存数据

    前言 在通常做项目的时候 需要存储数据 会使用GreenDAO数据库 bmob后端云 或者其他方法 以及本篇文章所讲解的本地缓存 也就是通过SharedPreferences 来进行缓存 第一部分 1 那么首先呢需要创建一个缓存数据的类Ca
  • python编程中的注意事项

    虚拟环境 win下的虚拟环境创建 virtualenv name python 3 7 9 conda创建虚拟环境 conda create prefix home coData venv python 3 8 conda环境恢复 起因 c
  • 我的128创作纪念日

    机缘 写CSDN博客的时候 应该纯属一个巧合 还记得当初是和一个班上的同学一起记录学习笔记 最初是在博客园的平台上记录笔记 可以在以后复习时使用 后来我的同学开始推荐使用CSDN平台 于是我们两就转战CSDN啦 不知不觉 从3月份到现在也有
  • PyQt中的多线程QThread示例

    PyQt中的多线程 一 PyQt中的多线程 二 创建线程 2 1 设计ui界面 2 2 设计工作线程 2 3 主程序设计 三 运行结果示例 一 PyQt中的多线程 传统的图形用户界面应用程序都只有一个执行线程 并且一次只执行一个操作 如果用
  • Vscode:常用插件 & 快捷键 & 配置等

    一 常用插件 1 git相关的 1 在代码中显示git提交日志 包含Git账号 commit信息 给Vscode添加Git功能 GitLens Git supercharged 2 显示图形化的瀑布时间线Git记录 可基于某个分支创建新分支
  • w10计算机怎么恢复出厂设置路由器,技术编辑为你解决win10系统打不开192.168.1.1设置界面的还原步骤...

    很多人都懂一些简单的电脑系统问题的解决方案 但是win10系统打不开192 168 1 1设置界面的情况 想必大家都遇到过win10系统打不开192 168 1 1设置界面的情况吧 那么应该怎么处理win10系统打不开192 168 1 1
  • 【SQL】5 SQL SELECT DISTINCT 语句

    SELECT DISTINCT 语句用于返回唯一不同的值 SQL SELECT DISTINCT 语句 在表中 一个列可能会包含多个重复值 有时您也许希望仅仅列出不同 distinct 的值 DISTINCT 关键词用于返回唯一不同的值 S
  • Vue 中如何实现监测数组变化

    vue中响应式数据的原理是通过Object defineProperty控制getter和setter 并利用观察者模式完成的响应式设计 数组考虑性能原因没有用defineProperty对数组的每一项进行拦截 而是选择重写数组api方法
  • git提交忽略文件名称大小写问题解决

    在项目开发中 关于文件名称大小写的修改 项目可能会默认忽略 对于一开始就新建的文件名问题不大 1 git在提交代码时 会忽略文件名称大小写 导致本地代码与远程代码不一致 此时可利用终端指令来检查下 git config get core i
  • 机械臂 手眼标定 手眼矩阵 eye-in-hand 原理、实践及代码

    1 手眼标定 所谓手眼系统 就是人眼睛看到一个东西的时候要让手去抓取 就需要大脑知道眼睛和手的坐标关系 而相机知道的是像素坐标 机械手是空间坐标系 所以手眼标定就是得到像素坐标系和空间机械手坐标系的坐标转化关系 目前工业上通常使用两种方法进
  • IDEA下导入maven项目时Maven Project处未能显示jar包正常解决办法

    IDEA下导入多级maven项目时未能显示正常解决办法 1 Ctrl Alt Shift S 打开Project Structrue 2 左边点击 Modules 切换到Modules选项卡 3 此时你如果发现现在已经加载所有工程中并没有你
  • IPSEC流程例子及两个阶段的协商过程详细介绍

    IPSEC VPN两个阶段的协商过程详细介绍 IPSec体系结构模型图 我们来看一个完整的IPSec体系结构模型图 以便更好地理解IPSec体系结构 IPSec流程图 SAKMP IKE第一阶段称为ISAKMP IKE的管理连接阶段 使用双
  • docker中镜像和容器的批量操作

    1 批量删除镜像 docker rmi docker images grep 条件 awk print 3 docker images 所展示的列表 第三列为镜像id 根据镜像id做删除操作 2 批量删除容器 docker rm f doc
  • 华为OD机试 - 最长广播响应(Java)

    题目描述 某通信网络中有N个网络结点 用1到N进行标识 网络中的结点互联互通 且结点之间的消息传递有时延 相连结点的时延均为一个时间单位 现给定网络结点的连接关系link i u v 其中u和v表示网络结点 当指定一个结点向其他结点进行广播
  • 因果推断(四)——后门调整、前门调整、逆概率加权

    在因果推断 三 中 我们介绍了干预的相关概念 在本文中 我们对一些方法进行介绍 这些方法可用于利用干预分析变量之间的因果关系 在因果推断 三 中 我们得出了调整公式 如上式 假设PA为A节点的所有父节点的集合 则上 式可以修改为 其中b为P
  • 架构与思维:系统容量设计

    背景 单位每年都会举行运动会 有一个2000m长跑的项目 大约每年报名人员为男选手40人 女选手20人 只有一条橡胶跑道 一次比赛10人齐跑 所以至少需要6场比赛 2000米的完成时间要求是20分钟 超过20分钟不计数 所以比赛耗时我们计算
  • Multi-Scale Convolutional Neural Networks for Time Series Classification

    keywords 时间序列处理 深度学习 keras 针对现有时间序列分类方法的特征提取与分类过程分离 且无法提取存在于不同时间尺度序列的不同特征的问题 作者提出MCNN模型 对于单一时间序列输入 进行降采样和滑动平均等变化 产生多组长度不
  • 双向dc-dc变换器原理

    buck电路原理 电容用于平滑电压 由于电容电压不能突变 所以再接一个电感 二极管的作用是给电感提供续流作用 boost电路原理 由于直接升压难以实现 理想情况下输入输出功率相同 可以通过减小输出电流来实现提高输出电压 双向dc dc变换器
  • Open3D 格网法计算点云的占地面积

    目录 一 算法原理 二 代码实现 三 结果展示 四 测试数据 一 算法原理 该方法主要用于粗略统计机载点云的占地面积 方法原理是将点云沿 X O Y XOY XOY面划分成格网 统计有点的格网面积来近似表示点云占地面积 二 代码实现
  • Android 加载高清巨图,无需剪裁压缩

    LargeImage Android 加载大图 可以高清显示10000 10000像素的图片 可以滑动 放大缩小具有PhotoView的效果 普通图片也可以用它展示 Gradle compile com shizhefei LargeIma