Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 查看android屏幕后比较位图-比较方法不起作用_Java_Android_Bitmap - Fatal编程技术网

Java 查看android屏幕后比较位图-比较方法不起作用

Java 查看android屏幕后比较位图-比较方法不起作用,java,android,bitmap,Java,Android,Bitmap,我试着比较两个不同的视图来比较图像,看它是否相同。这是我的密码 public boolean equals(View view1, View view2){ view1.setDrawingCacheEnabled(true); view1.buildDrawingCache(); Bitmap b1 = view1.getDrawingCache(); view2.setDrawingCacheEnabled(true); view2.buildD

我试着比较两个不同的视图来比较图像,看它是否相同。这是我的密码

public boolean equals(View view1,  View view2){

    view1.setDrawingCacheEnabled(true);
    view1.buildDrawingCache();
    Bitmap b1 = view1.getDrawingCache();

    view2.setDrawingCacheEnabled(true);
    view2.buildDrawingCache();
    Bitmap b2 = view2.getDrawingCache();

    ByteBuffer buffer1 = ByteBuffer.allocate(b1.getHeight() * b1.getRowBytes());
    b1.copyPixelsToBuffer(buffer1);

    ByteBuffer buffer2 = ByteBuffer.allocate(b2.getHeight() * b2.getRowBytes());
    b2.copyPixelsToBuffer(buffer2);

    return Arrays.equals(buffer1.array(), buffer2.array());
}

然而,无论发生什么,这都是真实的。有人能告诉我为什么我做错了吗?

不确定该代码有什么问题,如果有的话,但您尝试过了吗?

更新:下面的代码工作正常,但上面的代码似乎总是从.getDrawingCache()返回null不确定这是否是您的问题。我没有时间深入研究这个问题,但您可以查看类似问题是如何解决的,否则请提供logcat


这里是API 15中sameAs函数的一个端口(没有严格检查),它是在API 12中引入的

他们所做的一项特殊检查是查看图像是否为alpha通道,如果可能的话(可能不是您的用例的问题),进行一些优化以避免阵列检查,还可以在可能的情况下利用开源;-)

boolean SameAs(位图A、位图B){
//不同类型的图像
如果(A.getConfig()!=B.getConfig())
返回false;
//不同尺寸
如果(A.getWidth()!=B.getWidth())
返回false;
如果(A.getHeight()!=B.getHeight())
返回false;
//分配数组-可以,因为最坏情况下我们有3个字节+Alpha(?)
int w=A.getWidth();
int h=A.getHeight();
int[]argbA=新int[w*h];
int[]argbB=新int[w*h];
A.getPixels(argbA,0,w,0,0,w,h);
B.getPixels(argbB,0,w,0,0,w,h);
//阿尔法通道特殊检查
if(A.getConfig()==Config.ALPHA_8){
//在这种情况下,我们必须手动比较alpha通道,因为其余通道都是垃圾。
最终整数长度=w*h;
for(int i=0;i
@Idistic的回答帮助我找到了另一个解决方案,该解决方案同样适用于分辨率较高的图像,这可能会导致
内存溢出
错误。其主要思想是将图像分成几个部分并比较它们的字节。在我的情况下,10个零件就足够了,我认为对于大多数情况来说就足够了

private boolean compareBitmaps(Bitmap bitmap1, Bitmap bitmap2)
{
    if (Build.VERSION.SDK_INT > 11)
    {
        return bitmap1.sameAs(bitmap2);
    }

    int chunkNumbers = 10;
    int rows, cols;
    int chunkHeight, chunkWidth;
    rows = cols = (int) Math.sqrt(chunkNumbers);
    chunkHeight = bitmap1.getHeight() / rows;
    chunkWidth = bitmap1.getWidth() / cols;

    int yCoord = 0;
    for (int x = 0; x < rows; x++)
    {
        int xCoord = 0;
        for (int y = 0; y < cols; y++)
        {
            try
            {
                Bitmap bitmapChunk1 = Bitmap.createBitmap(bitmap1, xCoord, yCoord, chunkWidth, chunkHeight);
                Bitmap bitmapChunk2 = Bitmap.createBitmap(bitmap2, xCoord, yCoord, chunkWidth, chunkHeight);

                if (!sameAs(bitmapChunk1, bitmapChunk2))
                {
                    recycleBitmaps(bitmapChunk1, bitmapChunk2);
                    return false;
                }

                recycleBitmaps(bitmapChunk1, bitmapChunk2);

                xCoord += chunkWidth;
            }
            catch (Exception e)
            {
                return false;
            }
        }
        yCoord += chunkHeight;
    }

    return true;
}

private boolean sameAs(Bitmap bitmap1, Bitmap bitmap2)
{
    // Different types of image
    if (bitmap1.getConfig() != bitmap2.getConfig())
        return false;

    // Different sizes
    if (bitmap1.getWidth() != bitmap2.getWidth())
        return false;

    if (bitmap1.getHeight() != bitmap2.getHeight())
        return false;

    int w = bitmap1.getWidth();
    int h = bitmap1.getHeight();

    int[] argbA = new int[w * h];
    int[] argbB = new int[w * h];

    bitmap1.getPixels(argbA, 0, w, 0, 0, w, h);
    bitmap2.getPixels(argbB, 0, w, 0, 0, w, h);

    // Alpha channel special check
    if (bitmap1.getConfig() == Bitmap.Config.ALPHA_8)
    {
        final int length = w * h;
        for (int i = 0; i < length; i++)
        {
            if ((argbA[i] & 0xFF000000) != (argbB[i] & 0xFF000000))
            {
                return false;
            }
        }
        return true;
    }

    return Arrays.equals(argbA, argbB);
}

private void recycleBitmaps(Bitmap bitmap1, Bitmap bitmap2)
{
    bitmap1.recycle();
    bitmap2.recycle();
    bitmap1 = null;
    bitmap2 = null;
}
专用布尔比较器位图(位图位图位图1、位图位图位图位图2)
{
如果(Build.VERSION.SDK_INT>11)
{
返回bitmap1.sameAs(bitmap2);
}
整数=10;
int行,cols;
int chunkHeight,chunkWidth;
rows=cols=(int)Math.sqrt(chunkNumbers);
chunkHeight=bitmap1.getHeight()/行;
chunkWidth=bitmap1.getWidth()/cols;
int yCoord=0;
对于(int x=0;x
我得到一个错误“类型位图的方法sameAs(位图)未定义”,该方法被标记-因为:API级别12-所以我猜不适用于您的平台版本。当我将此复制到我的代码中时,它在“A.getPixels()”-@LiLi Liu处崩溃,我使用相同的、不同大小的,同样大小不同的内容,效果很好。请发布您的logcat输出,以便我们可以看到确切的错误。请参阅下面我的回复。我还尝试了上面的代码,它总是从读取文档的.getDrawingCache()返回空的位图,看起来它需要绘制视图-请参阅更新的响应
private boolean compareBitmaps(Bitmap bitmap1, Bitmap bitmap2)
{
    if (Build.VERSION.SDK_INT > 11)
    {
        return bitmap1.sameAs(bitmap2);
    }

    int chunkNumbers = 10;
    int rows, cols;
    int chunkHeight, chunkWidth;
    rows = cols = (int) Math.sqrt(chunkNumbers);
    chunkHeight = bitmap1.getHeight() / rows;
    chunkWidth = bitmap1.getWidth() / cols;

    int yCoord = 0;
    for (int x = 0; x < rows; x++)
    {
        int xCoord = 0;
        for (int y = 0; y < cols; y++)
        {
            try
            {
                Bitmap bitmapChunk1 = Bitmap.createBitmap(bitmap1, xCoord, yCoord, chunkWidth, chunkHeight);
                Bitmap bitmapChunk2 = Bitmap.createBitmap(bitmap2, xCoord, yCoord, chunkWidth, chunkHeight);

                if (!sameAs(bitmapChunk1, bitmapChunk2))
                {
                    recycleBitmaps(bitmapChunk1, bitmapChunk2);
                    return false;
                }

                recycleBitmaps(bitmapChunk1, bitmapChunk2);

                xCoord += chunkWidth;
            }
            catch (Exception e)
            {
                return false;
            }
        }
        yCoord += chunkHeight;
    }

    return true;
}

private boolean sameAs(Bitmap bitmap1, Bitmap bitmap2)
{
    // Different types of image
    if (bitmap1.getConfig() != bitmap2.getConfig())
        return false;

    // Different sizes
    if (bitmap1.getWidth() != bitmap2.getWidth())
        return false;

    if (bitmap1.getHeight() != bitmap2.getHeight())
        return false;

    int w = bitmap1.getWidth();
    int h = bitmap1.getHeight();

    int[] argbA = new int[w * h];
    int[] argbB = new int[w * h];

    bitmap1.getPixels(argbA, 0, w, 0, 0, w, h);
    bitmap2.getPixels(argbB, 0, w, 0, 0, w, h);

    // Alpha channel special check
    if (bitmap1.getConfig() == Bitmap.Config.ALPHA_8)
    {
        final int length = w * h;
        for (int i = 0; i < length; i++)
        {
            if ((argbA[i] & 0xFF000000) != (argbB[i] & 0xFF000000))
            {
                return false;
            }
        }
        return true;
    }

    return Arrays.equals(argbA, argbB);
}

private void recycleBitmaps(Bitmap bitmap1, Bitmap bitmap2)
{
    bitmap1.recycle();
    bitmap2.recycle();
    bitmap1 = null;
    bitmap2 = null;
}