检查图像是全白还是全透明的最快方法

时间:2014-05-23 15:07:43

标签: java android

如何有效地找出PNG是否只包含白色和透明像素?我的输入图片基本上是透明的,上面有一些手写笔记。认可必须非常可靠。我的当前代码在加载位图后循环所有像素,但执行时间太长。我正在寻找更好/更快的解决方案。

public static boolean isEmpty(Bitmap bmp)
{
    int[] pixels = new int[bmp.getWidth() * bmp.getHeight()];
    bmp.getPixels(pixels, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());
    for (int i : pixels)
    {
        if (!(Color.alpha(i) == 0 || (Color.blue(i) == 255 && Color.red(i) == 255 && Color.green(i) == 255)))
            return false;
    }
    return true;
}

4 个答案:

答案 0 :(得分:2)

另一个想法可能是:

1 - 将图片缩小到非常小的尺寸(例如100 x 100像素) 2 - 分析嵌套for循环中的每个像素颜色(对于y包括x - 反之亦然) 3 - 如果所有这些10000像素的alpha都为0(只需使用一个计数器,每次检查的像素的alpha为0时,你都会增加),你可以很好地近似确认​​图像是完全透明的。

答案 1 :(得分:1)

我认为有史以来最快的方法是直接分析PNG源,甚至不用解压缩来构建位图。我尝试了不同大小的图像,每个图像只有一种颜色(例如全绿色,全红色,全黑色,全透明),用十六进制编辑器查看字节,我发现输出PNG非常小(非常明显) ,给定非常小的熵),IDAT部分包含重复模式(随图像大小增长)。

我正在研究如何理解IDAT部分和位模式以提供代码示例,但我认为这种方法可行。

另一方面,通过对位图上的像素进行采样,您只有一个统计答案,我的意思是" 99%它是空的" ,或" 85%它是空的" :你不能通过不检查所有像素来肯定地告诉是/否(当然!可能正是你要找的东西)

答案 2 :(得分:1)

一种优化循环的方法(即使没有基准,我们也可以说多少)在语言级别(避免函数调用,假设运行时已经没有这样做):

for (int pixel : pixels) {
  if ((pixel & 0xFF000000) != 0 || (pixel & 0xFFFFFF) != 0xFFFFFF) return false;
}

答案 3 :(得分:0)

所有Alpha通道设置为0的图像不为空。无论每个像素的内容如何,​​它都与图像的分辨率一样大。

考虑到这一点,如果你想在不检查所有内容的情况下尝试查看图像是否“隐身”,最好的办法是对像素进行随机抽样并检查它们。这个确实有可能给你一个假阳性或假阴性,但它足够可靠,可以持续使用。我将给出一个测试100个随机像素的示例,但是当您感觉舒服时,可以提高或降低该像素。

public static boolean isEmpty(Bitmap bmp)
{
    Random rand = new Random();
    int currentPixel;
    for(int i = 0; i < 100; i++)
    {
        currentPixel = bmp.getPixel(rand.getNextInt(bmp.getWidth(), rand.getNextInt(bmp.getHeight());
        if(Color.alpha(currentPixel) == 0)
        {
            return false;
        }
    }
    return true;
}

由于我不知道您正在测试的图像的性质,您可以使用的指标是检查图像的5%随机像素样本。