WinForms位图区域已被锁定

时间:2016-01-25 02:12:39

标签: c# winforms exception bitmap byte

我试图滑过一些图像,基本上你有两个按钮向前和向后。它们的功能是滚动列表图像。一旦其中一个到达终点,它必须返回到列表的另一侧。这就是我所拥有的

{ "$ref": "http://some.site.somewhere/entry-schema#definitions/elementId" }

这是2个按钮。在这里,我试图将保存图像的pictureBox图像与列表private List<Bitmap> RotatePacks = new List<Bitmap> { new Bitmap(@"Assets\All_Cards\All_Royal\All_Royal.png"), new Bitmap(@"Assets\All_Cards\All_Classic\All_Classic.jpg")}; private void bNext_Click(object sender, EventArgs e) { Bitmap currentImage = (Bitmap)pickCards.Image; for (int i = 0; i < RotatePacks.Count; i++) { if (AreEqual(currentImage, RotatePacks[i])) { try { pickCards.Image = RotatePacks[i + 1]; } catch (Exception) { bPrevious_Click(sender, e); pickCards.Image = RotatePacks[i - 1]; } } } } private void bPrevious_Click(object sender, EventArgs e) { Bitmap currentImage = (Bitmap)pickCards.Image; for (int i = 0; i < RotatePacks.Count; i++) { if (AreEqual(currentImage, RotatePacks[i])) { try { pickCards.Image = RotatePacks[i - 1]; } catch (Exception) { bNext_Click(sender, e); } } } } 进行比较。像这样即时获取正在显示的当前图像。这是AreEqual方法:

RotatePacks

现在回到我的问题,按钮按照我想要的方式工作,但它们只工作一次。如果我按下下一个按钮而不是按钮,或按下两次按钮,程序将崩溃。它给了我这里的例外

public unsafe static bool AreEqual(Bitmap b1, Bitmap b2) // copy pasted
{
    if (b1.Size != b2.Size)
    {
        return false;
    }

    if (b1.PixelFormat != b2.PixelFormat)
    {
        return false;
    }

    /*if (b1.PixelFormat != PixelFormat.Format32bppArgb)
    {
        return false;
    }*/
    Rectangle rect = new Rectangle(0, 0, b1.Width, b1.Height);
    BitmapData data1
        = b1.LockBits(rect, ImageLockMode.ReadOnly, b1.PixelFormat);
    BitmapData data2
        = b2.LockBits(rect, ImageLockMode.ReadOnly, b1.PixelFormat);
    int* p1 = (int*)data1.Scan0;
    int* p2 = (int*)data2.Scan0;
    int byteCount = b1.Height * data1.Stride / 4; //only Format32bppArgb 

    bool result = true;
    for (int i = 0; i < byteCount; ++i)
    {
        if (*p1++ != *p2++)
        {
            result = false;
            break;
        }
    }

    b1.UnlockBits(data1);
    b2.UnlockBits(data2);

    return result;
}

以下是实际例外的一些屏幕截图:

http://prntscr.com/9ug3nl

http://prntscr.com/9ug3vv

  • P.S Im使用这种比较方法,但我没有编程。我从另一个StackOverflow问题中复制了代码

2 个答案:

答案 0 :(得分:1)

这里似乎有几个问题:

  1. 值得早点检查

    if (b1 == b2) //put this
        return true; 
    //do something else
    Rectangle rect = new Rectangle(0, 0, b1.Width, b1.Height);
    //and so on
    

    可能b1 == b2会导致该问题

  2. 好像您的LockBits引用相同的确切项目(相同的rect,相同的尺寸,某种模式,相同的像素格式):

    Rectangle rect = new Rectangle(0, 0, b1.Width, b1.Height);
    BitmapData data1
        = b1.LockBits(rect, ImageLockMode.ReadOnly, b1.PixelFormat);
    BitmapData data2
        = b2.LockBits(rect, ImageLockMode.ReadOnly, b1.PixelFormat);
    

    这可能是问题的另一个原因......

答案 1 :(得分:0)

就像Ian指出的那样,你必须检查你试图用AreEqual()方法(current imageRotatepacks[i]中的那个)进行比较的图像是否相同且属于同一个实例与否?如果它们属于同一个实例,它显然会产生该异常。使用.Equals()方法检查图像是否属于同一个实例。

考虑一个图像实例

Bitmap img;

img中的图片已加载到图片框以及RotatePacks中。在您的代码中,您尝试将同一个实例锁定两次,以便生成异常 Ian指出的位图线是好的..,2个不同的图像可以具有相同的大小和像素格式。

如果确实如此,我认为你不需要逐像素地进行比较。我想你Bitmap中有Rotatepacks个实例。只需使用Rotatepacks

将图片框中的图片实例与.Equals()中的图片实例进行比较