android pdf框架-10,相册浏览

MupdfViewer 这是最后apk,源码在前面的文章已经贴过了本站下载地址,只是不是最新的.可能不少是旧的内容.

subsampling-scale-image-view这是一个大图片的分块加载的实现.比较不错的.滑动方面我觉得使用flinger的效果比它要流畅,惯性要好.

也有人把这个作成pdf渲染器.但翻页就不好了.

现在的手机相册现在可能使用的是opengl实现的.

本项目中的,自定义flinger在滚动惯性上比其它要强一些.惯性太高,也会看到加载过程,反而会让人觉得慢...

多数的pdf阅读器都会用缓存.下文说到把块的缓存去了,原因之一是无法处理被回收的问题.另一个,缓存如果直接在主线程读取,因为它是同步的,会造成页面卡顿,滚动过程尤其明显.barteksc就是这样的,把它从scroller换成flinger实现滚动,就会明显感觉到卡顿,尤其在放大倍数提升到10倍后,对于barteksc,的10倍还不如我这边缩放4倍大,因为它是以最大的图片去计算的.

所以从这方面来说,我对改造后的效果还是挺满意的.

相册有很多,几乎全部是单张图片的浏览. 并不方便连续的浏览.

需求可能是这样的:

我在微博下了一些长图片,每一张在相册中查看当然可以,能放大,但是比较麻烦.

如果要生成pdf,会占了不少空间,而且照片会增加,比如拍照,会持续拍,总不能一直生成pdf,当然可以使用追加式的.

在浏览目录时,长按菜单,出现相册功能.按时间倒序排列查看.与pdf一样,所有的照片默认是同一个宽.不像barteksc它们都是保留原始宽,这样滑动后,可能容易内容滑出去了.这不是一个阅读器的好的体验方式.因为中间有一张特别宽的图片,会导致内容经常滑出去.

在pdf程序写好以后,我发现,既然生成的pdf可以,我也可以用pdf的浏览方式去查看相册.

相册图片解码速度比pdf还是要快不少的.目前没有针对三星这种拍照方向不对的照片处理.国内已经很少有三星手机了.

由于原来的pdfpage实现的接口,document等接口,添加一种实现即可.

class AlbumViewerActivity extends BaseViewerActivity {
    
    protected ProgressDialog progressDialog;
    
    @Override
    protected DecodeService createDecodeService() {
        return new DecodeServiceBase(new AlbumContext());
    }
    
    protected void loadDocument(String path) {
        progressDialog=new ProgressDialog(this);
        progressDialog.setMessage("Loading");
        progressDialog.show();
        
        AppExecutors.Companion.getInstance().diskIO().execute(() -> {
            decodeService.open(path);
            AppExecutors.Companion.getInstance().mainThread().execute(() -> {
                progressDialog.dismiss();
                documentView.showDocument();
            });
        });
    }
}

对activity作一次重构,把加载文档放到异步线程中,因为这不是加载pdf文档,是加载一个目录下的所有图片,有可能比较耗时.

加一个context

class AlbumContext implements CodecContext {

    public CodecDocument openDocument(String fileName) {
        return AlbumDocument.openDocument(fileName);
    }

    public void setContentResolver(ContentResolver contentResolver) {
    }

    public void recycle() {
    }
}

然后就是文档

class AlbumDocument implements CodecDocument {

    ArrayList<File> files;
    int count = 0;

    private static FileFilter createFileFilter() {
        return pathname -> {
            if (pathname.isHidden()) {
                return false;
            }

            if (pathname.isDirectory())
                return false;
            String fname = pathname.getName().toLowerCase(Locale.ROOT);

            return AdapterUtils.INSTANCE.isImage(fname);
        };
    }

    public static AlbumDocument openDocument(String fname) {
        File[] fileArray = new File(fname).listFiles(createFileFilter());
        ArrayList<File> files = new ArrayList<>(fileArray != null ? Arrays.asList(fileArray) : Collections.<File>emptyList());
        Collections.sort(files, (o1, o2) -> {
            if (o1 == null && o2 == null) {
                return 0;
            }
            if (o1.isDirectory() && o2.isFile()) return -1;
            if (o1.isFile() && o2.isDirectory()) return 1;
            if (o1.lastModified() - o2.lastModified() > 0) {
                return -1;
            } else if (o1.lastModified() - o2.lastModified() < 0) { //jdk7以上需要对称,自反,传递性.
                return 1;
            } else {
                return 0;
            }
        });
        AlbumDocument document = new AlbumDocument(files);
        return document;
    }

    public AlbumDocument(ArrayList<File> files) {
        this.files = files;
        if (null != files) {
            count = files.size();
        }
    }

    public CodecPage getPage(int pageNumber) {
        return AlbumPage.createPage(files.get(pageNumber).getAbsolutePath(), pageNumber);
    }

    public int getPageCount() {
        return count;
    }

    @Override
    protected void finalize() throws Throwable {
        recycle();
        super.finalize();
    }

    public synchronized void recycle() {
    }

    @Override
    public Outline[] loadOutline() {
        return new Outline[0];
    }
}

要过滤出支持解码的图片类型,svg目前不行.

最关键的还是解码部分. 这里对每一块解码都可能重新生成一个decoder,可以优化一下.

class AlbumPage implements CodecPage {

    private long pageHandle = -1;
    int pageWidth;
    int pageHeight;
    private BitmapRegionDecoder decoder;
    private String path;

    static AlbumPage createPage(String fname, int pageno) {
        AlbumPage pdfPage = new AlbumPage(pageno, fname);
        return pdfPage;
    }

    public AlbumPage(long pageno, String fname) {
        this.pageHandle = pageno;
        this.path = fname;
    }

    public int getWidth() {
        if (pageWidth == 0) {
            decodeBound();
        }
        return pageWidth;
    }

    private void decodeBound() {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        pageWidth = options.outWidth;
        pageHeight = options.outHeight;
    }

    public int getHeight() {
   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/497982.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

低功耗、低成本 NAS/公共文件夹 的可能性

使用现状&#xff1a;多台工作电脑&#xff0c;家里人手一台&#xff0c;还在两个住处 有好几台工作电脑&#xff0c;不同电脑不同OS有不同的用途&#xff0c;最大的问题就是各个电脑上文件的同步问题&#xff0c;这里当然就需要局域网里的公共文件夹&#xff0c;在NAS的问题上…

R语言使用dietaryindex包计算NHANES数据多种营养指数(2)

健康饮食指数 (HEI) 是评估一组食物是否符合美国人膳食指南 (DGA) 的指标。Dietindex包提供用户友好的简化方法&#xff0c;将饮食摄入数据标准化为基于指数的饮食模式&#xff0c;从而能够评估流行病学和临床研究中对这些模式的遵守情况&#xff0c;从而促进精准营养。 该软件…

Unity3d使用Jenkins自动化打包(Windows)(一)

文章目录 前言一、安装JDK二、安装Jenkins三、Jenkins插件安装和使用基础操作 实战一基础操作 实战二 四、离线安装总结 前言 本篇旨在介绍基础的安装和操作流程&#xff0c;只需完成一次即可。后面的篇章将深入探讨如何利用Jenkins为Unity项目进行打包。 一、安装JDK 1、进入…

【嵌入式机器学习开发实战】(十二)—— 政安晨:通过ARM-Linux掌握基本技能【C语言程序的安装运行】

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 嵌入式机器学习开发实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 在ARM-Linux系统中&#xff0c;C语言程序的安装和运行可…

快速上手Spring Cloud 六:容器化与微服务化

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

啥也不会的大学生看过来,这8步就能系统入门stm32单片机???

大家好&#xff0c;今天给大家介绍啥也不会的大学生看过来&#xff0c;这8步就能系统入门stm32单片机&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 对于没有任何基础的大学生来…

数据库原理与应用(SQL Server)笔记 关系数据库

目录 一、关系数据库的基本概念&#xff08;一&#xff09;关系数据库的定义&#xff08;二&#xff09;基本表、视图&#xff08;三&#xff09;元组、属性、域&#xff08;四&#xff09;候选码、主码、外码 二、关系模型三、关系的完整性&#xff08;一&#xff09;实体完整…

快速上手Spring Cloud五:Spring Cloud与持续集成/持续部署(CI/CD)

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

神策数据参与制定首份 SDK 网络安全国家标准

国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff08;2023 年第 13 号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的 3 项国家标准正式发布。其中&#xff0c;首份 SDK 国家标准《信息安全技术 移动互联网应用程序&#xff0…

根据实例逐行分析NIO到底在做什么

Selector&#xff08;选择器&#xff09;是 Channel 的多路复用器&#xff0c;它可以同时监控多个 Channel 的 IO 状况&#xff0c;允许单个线程来操作多个 Channel。Channel在从Buffer中获取数据。 选择器、通道、缓冲池是NIO的核心组件。 一、新建选择器 此时选择器内只包含…

HackTheBox-Machines--Legacy

文章目录 1 端口扫描2 测试思路3 445端口漏洞测试4 flag Legacy 测试过程 1 端口扫描 nmap -sC -sV 10.129.227.1812 测试思路 目标开启了135、139、445端口&#xff0c;445 SMB服务存在很多可利用漏洞&#xff0c;所以测试点先从445端口开始。而且在Nmap扫描结果中&#xff0c…

操作系统练习-操作系统的发展与分类

批量处理系统 ----------------------------------------------------------------------------------------------------------------------------- 1. 下列关于批处理系统的叙述中&#xff0c;正确的是( )。 I.批处理系统允许多个用户与计算…

百度智能云千帆,产业创新新引擎

本文整理自 3 月 21 日百度副总裁谢广军的主题演讲《百度智能云千帆&#xff0c;产业创新新引擎》。 各位领导、来宾、媒体朋友们&#xff0c;大家上午好。很高兴今天在石景山首钢园&#xff0c;和大家一起沟通和探讨大模型的发展趋势&#xff0c;以及百度最近一段时间的思考和…

camtasia怎么添加背景图 camtasia怎么添加背景音乐

在进行视频编辑时&#xff0c;添加合适的背景图和背景音乐是很重要的。美观的背景图可以增强视频的视觉体验&#xff0c;让画面更加生动和谐&#xff0c;而添加背景音乐&#xff0c;则能够调节气氛&#xff0c;让观众更好地沉浸到视频中。接下来我将为大家介绍&#xff1a;camt…

专题:一个自制代码生成器(嵌入式脚本语言)之应用实例

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 专题&#xff1a;一个自制代码…

网络原理-传输层-UDP报文结构

本文介绍UDP报文 有很多友友搞不清楚UDP报文的详细结构还有TCP的详细结构,所以专门分开来讲 以免弄混. 首先我们先看一下整个UDP结构,让大家有一个全方面的认识 下面我们来详细解释UDP报 16位源端口号(本机):就是2字节大小,16个二进制位. 16位目的端口号(目的机):也是2字节…

element-ui autocomplete 组件源码分享

紧接着 input 组件的源码&#xff0c;分享带输入建议的 autocomplete 组件&#xff0c;在 element-ui 官方文档上&#xff0c;没有这个组件的 api 目录&#xff0c;它的 api 是和 input 组件的 api 在一起的&#xff0c;看完源码之后发现&#xff0c;源码当中 autocomplete 组件…

MTK8781安卓核心板_MT8781(Helio G99)核心板性能参数

MT8781安卓核心板搭载了八核CPU&#xff0c;其中包括两个主频高达2.2GHz的高性能Arm Cortex-A76处理器。这一处理器采用了台积电6纳米级芯片生产工艺&#xff0c;以及先进的3D图形功能的高性能Arm Mali G57级GPU。通过超快LPDDR4X内存和UFS 2.2存储供电&#xff0c;不仅提高了游…

新版Idea2023.3.5与lombok冲突、@Data失效

新版idea和lombok冲突&#xff0c;加上Data&#xff0c;其他地方get set也不报错&#xff0c;但是一运行就找不到get set方法。 但是直接使用Getter和Setter可以访问、应该是Data失效了。 解决方法&#xff1a; 看推上介绍是 lombok 与 idea 采集 get 、set 方法的时候所用的技…

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…
最新文章