android pdf框架

2023-11-14

系列文章目录

第一章 android pdf框架


前言

pdf已经使用很普遍了,android上的好用的pdf工具也有不少,个人更经常是用于阅读,很少标记,所以有一个适合的阅读器对我来说非常重要了.

我需要记录阅读历史,收藏优质的图书,pdf文件浏览器,在不同的手机上需要同步数据(不通过服务器,可以导出内容),可以自动切边.

自己写一个阅读器是不是太闲了,市面上有静读天下,ebookdroid都是非常优秀的阅读器,只不过对于来说,需求没匹配上,因为我读了几百上千本书,还有很多没有读的,需要一个好的文件浏览器,ebookdroid本来是很好的,但滚动上有问题,横竖切换有bug一直没有更新了.静读天下是基于pdfmaster,有些pdf的中文显示不了.


提示:以下是本篇文章正文内容,下面案例可供参考

一、主流的pdf解析库有哪些

pdfium/福昕sdk,自谷歌买了以后,pdfium开源了,不少基于它的库,支持多平台.

mupdf,这是非常不错的解析库,开源,而且它还支持xps,epub,mobi,svg等,也支持导出文本时带上base编码的图片,pdfium只支持导出文本.多平台.(近期的授权似乎开始变了)

xpdf,移动端没有看到有适配.

itext,自4.0以后就不免费用了,需要授权(除非你的app也开源),支持多平台,功能完善,文档齐全,就是不便宜.

openpdf,在4.0的itext上fork的

pdfbox,apache上纯java实现的库,速度不太理想.

二、有哪些优缺点

1.库对比

体积 页面渲染速度 渲染效果 使用难度 github数量 示例
android 系统21带的 简单 无法查询 简单
pdfium 64位的4.6mb 简单 repo:431 有开源项目
mupdf 64位的7.6mb 非常快 非常好 简单 repo:527 有官方示例

itext主要用于处理pdf文件,在这就不列出功能了.其它库不作介绍,目前android上解析上的使用量就是pdfium,mupdf两个为主.

实际使用中发现,pdfium这个库的显示与mupdf相比还是要差一些,扫描版与非扫描版本都是如此,可能是我写的有问题.

 

针对不同的pdf进行不同的测试,页面渲染速度取平均值,还是mupdf快几毫秒.

2.使用方式:

android系统带的,对系统版本有限制,必须在21以后.

ParcelFileDescriptor parcel = ParcelFileDescriptor.open(new File(path), ParcelFileDescriptor.MODE_READ_ONLY);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            PdfRenderer pdfRenderer = new PdfRenderer(parcel);

            PdfRenderer.Page page = pdfRenderer.openPage(index);
            float scale = 1.0f * width / page.getWidth();
            int nHeight = (int) (page.getHeight() * scale);
            Bitmap bitmap = Bitmap.createBitmap(
                    width,
                    nHeight,
                    Bitmap.Config.ARGB_8888
            );

            Log.d("PDFSDK", String.format("android width:%s, rootView.getHeight:%s, nHeight:%s,scale:%s, size:%s", width, height, nHeight, scale, page));
            page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
            BitmapUtils.saveBitmap(bitmap, "pdfium.jpg");
            pdfRenderer.close();
        }

2.pdfium自己编译的so,我使用的是基于

https://github.com/barteksc/PdfiumAndroid的jni
ParcelFileDescriptor parcel = ParcelFileDescriptor.open(new File(path), ParcelFileDescriptor.MODE_READ_ONLY);
        PdfiumSDK sdk = new PdfiumSDK();
        sdk.newDocument(parcel);

        sdk.openPage(index);
        Size size = sdk.getPageSize(index);
        float scale = 1.0f * width / size.getWidth();
        int nHeight = (int) (size.getHeight() * scale);
        Bitmap bitmap = Bitmap.createBitmap(
                width,
                nHeight,
                Bitmap.Config.ARGB_8888
        );

        Log.d("PDFSDK", String.format("pdfium width:%s, rootView.getHeight:%s, nHeight:%s,scale:%s, size:%s", width, height, nHeight, scale, size));
        sdk.renderPageBitmap(bitmap, index, 0, 0, bitmap.getWidth(), bitmap.getHeight(), false);
        BitmapUtils.saveBitmap(bitmap, "pdfium.jpg");
        sdk.closeDocument();

mupdf,基于https://git.ghostscript.com/?p=mupdf.git;a=summary

自己编译的

Document document = Document.openDocument(path);
        Page page = document.loadPage(index);

        float scale = 1.0f * width / (page.getBounds().x1 - page.getBounds().x0);
        int nHeight = (int) (scale * page.getBounds().y1 - page.getBounds().y0);
        com.artifex.mupdf.fitz.Matrix ctm = new com.artifex.mupdf.fitz.Matrix(scale);
        Bitmap bitmap = Bitmap.createBitmap(width, nHeight, Bitmap.Config.ARGB_8888);

        Log.d("PDFSDK", String.format("mupdf.width:%s, rootView.getHeight:%s, nHeight:%s,scale:%s, size:%s,ctm:%s", width, height, nHeight, scale, page.getBounds(), ctm));

        AndroidDrawDevice dev = new AndroidDrawDevice(bitmap, 0, 0, 0, 0, bitmap.getWidth(), bitmap.getHeight());

        page.run(dev, ctm, (Cookie) null);
        dev.close();
        dev.destroy();

        BitmapUtils.saveBitmap(bitmap, "mupdf.jpg");
        document.destroy();

由于字体的问题,非扫描版不同的库显示的效果是不一样的.

3.知名开源阅读器

基于pdfium的:barteksc/PdfiumAndroid,目前不维护了,但使用非常广泛.

基于mupdf的:官方的简单阅读器,ebookdroid已经有一段时间没有更新了,只有英文版了.

GitHub - archko/amupdf-android

这是我自己基于开源库修改的阅读器

 


总结

集成到现有的app中,会考虑体积,系统支持度,使用难易程度,功能等.

如果是21以上的,可以考虑使用系统的api,但不可定制.

21以下也需要支持的话,可以考虑pdfium与mupdf,mupdf如果去除额外文字支持,包也可以减少,但比较复杂.pdfium有体积方面的优势.mupdf不是只定位于pdf解析库,已经延伸到其它的解析了.

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

android pdf框架 的相关文章

  • 将数据从服务传递到活动

    我有自行运行的服务 服务自动启动 我有活动 在此 Activity 按钮中启动该方法DoIt Button setOnClickListener new OnClickListener public void onClick View v
  • 使用 JSONArray 还是普通数组来存储/读取数据更有效?

    我正在使用一个连接到PHP MySQL返回所有内容的服务器JSON格式 例如 用户列表作为JSONArray of JSONObject 每个对象都包含单个用户的信息 姓名 位置 电话号码等 处理这种格式的信息时 将所有内容保留在其中会更有
  • 应用程序在加载 xml 布局文件的主线程中做了太多工作

    我正在制作一个 9x9 数独网格 其中 81 个单元格本身就是一个 3x3 网格 单个细胞看起来像这样 1 2 3 4 5 6 7 8 9 每个数字代表该单元格的铅笔注释 我有一个名为 cell layout xml 的文件 表示这种 3x
  • Android 图表[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在开发一个项目 其中有一些图表 图形 刻度图 烛台图和范围图 但问题是 没有该图表的库 我有烛台图的
  • Android 中的列表(特别是 RecyclerView 和 CardView)如何工作

    请原谅我问这个问题 但我是 Android 开发新手 尽管我正在尝试了解developer android com 网站上的基础知识 但大多数示例 即使他们说它们是为 Android Studio 构建的 尚未设置为使用 Gradle 因此
  • 改造中的多个队列导致内存不足错误?

    我正在使用retrofit2 做我的项目 当我的呼叫失败时 我再次重复相同的呼叫 重复此 呼叫使我的应用程序强制关闭 当我查看日志时 我得到了错误日志 如下所示 我觉得这是由于同一呼叫的多次排队造成的 所以我在排队之前就这样做了 我打电话给
  • Android 全屏对话框确认和拒绝操作

    材料设计中的全屏对话框应该在操作栏 工具栏上有确认和拒绝操作 我的问题是 我该怎么做 显示对话框 getFragmentManager beginTransaction add R id container new MyDialogFrag
  • 退出设备上的 system.img

    我正在为我们部署给客户的设备 LG p509 Optimus 1 开发自动应用程序更新解决方案 我们可以控制这些设备 并且目前在它们上安装自定义内核 但不是完整的自定义 ROM 由于我们试图在设备上自动更新我们的应用程序 因此我们需要由我们
  • ExpandableListview OnGroupClickListener 未触发

    我正在关注这个 以编程方式折叠 ExpandableListView 中的组 https stackoverflow com questions 4314777 programmatically collapse a group in ex
  • 选项卡主机内的 Android Fragment 视图状态 [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Fragment 为 Android 中的每个选项卡单独的返回堆栈 https stackoverflow com questions 6987334 separate back stack f
  • 在新的 intel x86 android 模拟器中访问 google api

    我只是尝试在新的 x86 android 模拟器中运行我公司的应用程序 但是我们的应用程序依赖于 google 地图 API 而这在 google 随 android sdk 版本 17 提供的 x86 系统映像中不可用 我的直觉告诉我答案
  • 是否可以通过 Android 应用程序来录音?

    我是一名开发人员 希望创建一个 Android 应用程序来记录电话 这是出于我个人的需要 为了我自己的目的和记录而记录电话 是否有可能做到这一点 是否可以访问麦克风以及通过扬声器发出的声音 我对 Android 开发有点陌生 所以请耐心等待
  • 当 minifyEnabled 为 true 时 Android 应用程序崩溃

    我正在使用多模块应用程序 并且该应用程序崩溃时minifyEnabled true in the installed模块的build gradle 以下是从游戏控制台检索到的反混淆堆栈跟踪 FATAL EXCEPTION Controlle
  • Android NDK 代码中的 SIGILL

    我在市场上有一个 NDK 应用程序 并获得了有关以下内容的本机崩溃报告 SIGILL信号 我使用 Google Breakpad 生成本机崩溃报告 以下是详细信息 我的应用程序是为armeabi v7a with霓虹灯支持 它在 NVIDI
  • 安卓。 CalendarView...一次仅显示一个月的日历

    我正在使用 CalendarView 其中我想一次仅查看一个月的日历并滚动查看下个月 但 CalendarView 一次显示所有月份 下面是我的代码
  • Android SearchView 在启动时隐藏键盘

    我有一个小问题正在尝试解决 当我打开应用程序时 键盘会显示输入搜索视图的查询 不过 我只想在单击搜索视图时显示键盘 我该如何解决 Thanks 这对我有用 用于隐藏焦点的代码 searchView SearchView view findV
  • 如何将样式应用于我拥有的所有 TextView? [复制]

    这个问题在这里已经有答案了 可能的重复 设计所有 TextView 或自定义视图 的样式 而不向每个 TextView 添加样式属性 https stackoverflow com questions 6801890 styling all
  • Android-dispatchTouchEvent 给了我一个 StackOverflowError

    这里我有一个带有 setOnTouchListener 的 ViewFlipper 它工作得很好 然后我膨胀 ReLayNewsItem 然后将其添加到 ViewFlipper 现在我希望 WebView web 监听触摸事件并将它们传递给
  • 如何访问我的 Android 程序中的联系人

    我正在制作一个短信应用程序 并且想要访问我的 Android 应用程序中的联系人 我想访问联系人 就像他们在实际联系人列表中一样 选择后 我需要返回到我的活动 在其中我可以向该人发送短信 或者是否可以访问存储联系人的数据库 我的代码如下所示
  • Android GetPTLAFormat 上的 Phonegap 错误

    我们正在开发一个使用 jQuery 移动和电话间隙的应用程序 一切似乎都工作正常 但是当在连接的 Android 手机上运行应用程序时 我们在 Eclipse logcat 中看到大量类似这样的错误 0 GetPTLAFormat inva

随机推荐

  • 英语 动词过去式和过去分词的变化规则

    动词过去式和过去分词有规则变化和不规则变化两种 实例顺序 动词原形过去式过去分词 发音 ed在清辅音音素后发音为 t 在浊辅音后发音为 d 在元音后发音也为 d 在 t d 后发音为 id 一 规则变化 1 一般在动词原形后加 ed loo
  • 嵌套查询及其与join的区别

    嵌套即可以写在select子句中 也可以写在from子句中 下面以SQL Entity为例来说明 1 嵌套在select中 以父表为主在select中嵌套子表信息 SELECT c Title ANYELEMENT SELECT oa Fi
  • mysql联合索引最左匹配原则的底层实现原理

    mysql联合索引最左匹配原则的底层实现原理 要看懂 需要熟悉mysql b tree的数据结构 b tree的叶节点和叶子节点的排序特性是按照 从小到大 从左到右的这么一个规则 int直接比大小 uuid比较ASCII码 联合索引的排序规
  • 极简式 Unity 获取 bilibili 直播弹幕、SC、上舰、礼物等 插件

    极简式 Unity 获取 bilibili 直播弹幕 SC 上舰 礼物等 1 声明 下载链接 软件均仅用于学习交流 请勿用于任何商业用途 2 介绍 该项目为Unity实时爬取B站直播弹幕 项目介绍 通过传入B站直播间账号 实现监控B站直播弹
  • java threadlocal 详解_Java中的ThreadLocal深入理解详解

    提到 ThreadLocal是什么 ThreadLocal是一个关于创建线程局部变量的类 通常情况下 我们创建的变量是可以被任何一个线程访问并修改的 而使用ThreadLocal创建的变量只能被当前线程访问 其他线程则无法访问和修改 Glo
  • sha256的python实现

    在 Python 中可以使用 hashlib 库来实现 SHA 256 哈希算法 代码如下 import hashlib defsha256 data sha256 hashlib sha256 sha256 update data enc
  • 为什么printf只能用_cdecl调用约定

    1 什么是调用约定 调用约定 Calling conventions 和type representations 名称修饰 name mangling 同是应用二进制接口 application binary interface ABI 概
  • 分析rocketmq-client产生大量rocketmq_client.log日志文件的原因处理方案

    源码 public static final String CLIENT LOG USESLF4J rocketmq client logUseSlf4j public static final String CLIENT LOG ROOT
  • 05 两层神经网络 - 神经网络和深度学习 [Deep Learning Specialization系列]

    本文是Deep Learning Specialization系列课程的第1课 Neural Networks and Deep Learning 中Shallow Neural Network部分的学习笔记 在前面的章节中 我们以逻辑回归
  • Yolov5改进之更改损失函数(EIOU、SIOU)

    目录 1 修改metrics py文件 2 修改loss py函数 1 修改metrics py文件 找到bbox iou代码段 def bbox iou box1 box2 xywh True GIoU False DIoU False
  • 测试用例----测试大纲法

    一 应用场合 在一个程序中涉及多个窗口 每个窗口有多个操作 窗口和窗口之间有一定的联系 或者说操作之间的联系 为了弄清它们之间的联系 使用测试大纲法 二 使用测试大纲法分析程序 1 列大纲 提纲 分析需求 列出所有的窗口以及每个窗口包含的操
  • MQTT 固定报头 中 剩余长度字段的计算

    剩余长度 简介 位置 固定报头中 从第2个字节开始 剩余长度等于可变报头的长度 10字节 加上有效载荷的长度 剩余长度 Remaining Length 表示当前报文剩余部分的字节数 包括可变报头和负载的数据 剩余长度不包括用于编码剩余长度
  • 什么是区块链----概念

    前言 从2016年年初开始 区块链这个概念越来越热越来越火 有人说他可以颠覆金融行业 也有人觉得这就是个噱头 这个2016火起来的技术其实早在2008年 比特币的诞生就基于区块链 技术火归火 落地的应用却没有那么多 周围的朋友同学都听说过这
  • 搭建Serv-U FTP服务器共享文件外网远程访问「无公网IP」

    文章目录 1 前言 2 本地FTP搭建 2 1 Serv U下载和安装 2 2 Serv U共享网页测试 2 3 Cpolar下载和安装 3 本地FTP发布 3 1 Cpolar云端设置 3 2 Cpolar本地设置 4 公网访问测试 5
  • linux系统通过docker安装oracle远程访问(附带相关问题解决方案)

    文章目录 一 虚拟机网络配置 二 安装docker 三 拉取oracle镜像并配置 四 设置oracle支持外部连接访问 重难点 总结 一 虚拟机网络配置 虚拟机配置的方案 1 桥接模式 虚拟机和主机共用同一个网段 适用于固定网络的开发环境
  • auto refresh

    div user div
  • TCP为什么需要三次握手进行连接,二次或四次不可以吗?

    一 三次握手的作用 为了确认双方具有接收和发送的能力 二 三次握手的原因 1 可以阻止重复历史连接的初始化 主要原因 2 可以同步双方的初始序列号 3 可以避免资源的浪费 三 分析原因 1 为了防止旧的重复连接初始化造成混乱 当客户端发送了
  • 嵌入式软件中如何排查bug?

    明确Bug现象 要准确描述Bug出现的场景 现象 能复现就最好 查看日志信息 嵌入式系统日志可以帮助定位问题 看是否有报错 异常信息 用仿真工具调试 许多嵌入式芯片都有相应的仿真调试工具 可以在仿真环境下单步跟踪 查看变量值等 加打印调试
  • C# DataSet和DataTable:将查询结果保存到DataSet或DataTable中

    在执行对表中数据的查询时还能将数据保存到 DataSet 中 但需要借助 DataAdapter 类来实现 在实际应用中 DataAdapter 与 DataSet 是在查询操作中使用最多的类 此外 还可以通过 DataSet 实现对表中数
  • android pdf框架

    系列文章目录 第一章 android pdf框架 文章目录 系列文章目录 前言 一 主流pdf解析库有哪些 二 对比与使用 1 库对比 2 使用方式 总结 前言 pdf已经使用很普遍了 android上的好用的pdf工具也有不少 个人更经常