簡體   English   中英

WinForms位圖區域已被鎖定

[英]WinForms Bitmap region is already locked

我正在嘗試瀏覽一些圖像,基本上您有2個向前和向后的按鈕。 它們的功能是滾動列表圖像。 一旦其中一個到達末尾,就必須返回列表的另一側。 這就是我所擁有的

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);
            }
        }
    }
}

這些是2個按鈕。 在這里,我試圖將包含圖像的pictureBox的圖像與列表RotatePacks 像這樣,即時獲取正在顯示的當前圖像。 這是AreEqual方法:

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;
}

現在回到我的問題,按鈕的工作方式與我想要的一樣,但它們僅工作一次。 如果我按了下一個按鈕,而不是上一個按鈕,或者我按了下一個按鈕兩次,程序將崩潰。 這里給我例外

            BitmapData data2
            = b2.LockBits(rect, ImageLockMode.ReadOnly, b1.PixelFormat);

這是實際異常的一些屏幕截圖:

http://prntscr.com/9ug3nl

http://prntscr.com/9ug3vv

  • PS我使用這種比較方法,但我沒有編程。 我從另一個StackOverflow問題中復制了代碼

這里似乎有幾個問題:

  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); 

    這可能是造成此問題的另一個原因...

就像Ian指出的那樣,您必須檢查在AreEqual()方法中嘗試比較的current imagecurrent imageRotatepacks[i] )是否相同並且屬於同一實例? 如果它們屬於同一實例,則顯然會生成該異常。 使用.Equals()方法檢查圖像是否屬於同一實例。

考慮一個圖像實例

Bitmap img;

img的圖像已加載到圖片框以及RotatePacks 在您的代碼中,您嘗試將同一實例鎖定兩次,以便生成異常。Ian指出的位圖線還可以,.. 2個不同的圖像可以具有相同的大小和像素格式。

另外,如果確實是這樣,我認為您不需要逐像素比較。 我想您在RotatepacksBitmap實例。 只需使用.Equals()將圖片框中的圖像實例與Rotatepacks中的圖像實例進行比較

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM