android pdf框架-7,白边切割

本文探讨了在Android环境下,PDF阅读器中图片白边切割的重要性及优化策略。通过二值化算法和扫描优化,实现了高效精确的切边效果。详细介绍了普通切边与缩略图切边法,以及二值化算法的三种优化方法,包括0,1法、固定阈值法和双固定阈值法。此外,还分享了扫描算法的优化,如直接全图扫描、区域扫描法和扫描与二值化同时操作,以降低处理时间。最后,讨论了解码图片时的缩放处理,确保在保持精度的同时提高性能。" 122796969,366432,Halcon教程:fit_circle_contour_xld函数详解,"['计算机视觉', '图像处理', 'Halcon']
摘要由CSDN通过智能技术生成

图片的切边操作有时是比较有用的.看着舒服多了,页面间的空白如果比较大的图片在显示上,需要缩放,缩放后通常滚动会有偏移.

这里先说算法思路.

列表与切边

在解析列表中每一页,先解析白边,得到后,再去解码图片,最终显示.

对于分块加载的处理就比较麻烦了.对于recyclerview中使用单页面一个图片还是相对容易的多的.

由于切边算昂贵的操作,可以缓存在内存中,甚至可以存储在文件中,下次读取pdf后,可以直接把切边的数据读出去.

切边法有两个操作

直接原图切边与缩略图切边

原图的好处就是切的准确度高,但太大,效率低.

缩略图的好处就是速度快,准确度略低.

普通切边法

将图片二值化,然后从左,上,右,下开始扫描,扫描后得到的白边范围.

缩略图切边法

先生成一张缩略图,比如200*200 范围内的,然后用上面的切边法,去把空白区算出来.然后再把缩略图与原图的比例,与切边后的rect计算出原图应该切多少.

切边优化

对于缩略图,有时还是太慢.一张图如果全扫描也要10毫秒,这不太能接受,尤其如果是在滚动过程中的切边,然后再渲染图片,10毫秒接近图片解码的一半时间了,整个切边到渲染图片到列表中将达到40毫秒左右,也不是不能接受,pdfium这个库比mupdf的解码也是慢这么多.

切边算法优化
二值化算法优化
二值化,0,1法

普遍的是使用像素0与255,就是非0像素,白色的直接设置为255,0像素不变.这种方法容易识别图片产生错误.比如我解析三国演义的非扫描版pdf,它是带背景色为黄色的pdf,就无法正确识别它.

二值化,固定阈值法

就是固定的阈值,比如100,小于它都设置0,大于都设置255.其它与上相同.

二值化,双固定阈值法

设置两个阈值,小于下限,大于上限设置0,在中间的设置255,其它同一法.

无论哪种,最终要的是能切好白边,实际中,二三两种会比较有优势.

当然解析时,mupdf已经不支持565的图片,pdfium这个还可以,用它可以略内存,直接忽略alpha通道了.

扫描算法优化

对于切边的二值化算法完成后.进入切边操作.

直接全图扫描

整个缩略图二值化后的图片直接从左,上,右,下,分别扫描,直到找到非白区,返回结果.

这种操作就是耗资源多点,因为已经是缩略图了,速度还是能接受的.

区域扫描法

区域扫描法,这算不上什么算法,算是一种图片渲染策略,在上面的扫描方案基础上再优化.

比如一张图片,我最多切去2/3,那么我从左边向下扫描,可以设置扫描量最多是1/3,从右向左,最多1/3.那么左右方向可以省1/3的时间.

同理,上下扫描一样.

扫描与二值化同时操作

在上面的扫描方案中,不是事先准备好所有的二值化数据.针对的是缩略图原图操作

步骤:

从左开始,按行扫描,但一次扫描4行(多少行可修改),然后把这4行的数据进行二值化操作,然后确认空白区.如果是空白的,继续下一轮,直到扫扫描到非空白区.

其它方向同理.

二值化的只是部分区域,我扫到哪里就处理到哪里,可以省更多的时间,资源.

因为对整张图片二值化,也是耗时操作,很多页面没有必要这样处理,因为多数图片的内容区是有东西的.多数可能只扫描5行就得到了结果,剩下的100行都不要处理.尤其对于左,右,上这三边,可以省很多资源.对于下往上扫,就要看内容区多少了.

最终的耗时,从10毫秒减少到1毫秒.

这里借用一下别人的二值化文章,感谢.Android数字图像处理之二值化_android 图片二值化-CSDN博客

代码解析:

这里使用阈值二值化的方法:代码是网上找的,作了些小修改,不过原理是一样的.

/**
     * 灰度化 bitmap
     *
     * @param width
     * @param height
     * @param pixels
     * @return
     */
    private static void setGray(Bitmap bitmap, int width, int height, int[] pixels) {
        int alpha = 0xFF << 24;  //设置透明度
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int gray = pixels[width * i + j];
                int red = ((gray & 0x00FF0000) >> 16);  //获取红色灰度值
                int green = ((gray & 0x0000FF00) >> 8); //获取绿色灰度值
                int blue = (gray & 0x000000FF);         //获取蓝色灰度值
                gray = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
               
                if(gray < 180) {//如果某点像
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值