2016-01-25 2 views
1

Я пытаюсь скользить по нескольким изображениям, в основном у вас есть 2 кнопки вперед и назад. Они предназначены для прокрутки изображений списка. Как только один из них достигнет конца, он должен вернуться на другую сторону списка. Вот что у меня естьWinForms Растровая область уже заблокирована

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 Im используя этот метод сравнения, но я не программировать , Я скопировал код из другого StackOverflow вопрос
+0

Это просто дикая догадка сейчас ... но вы не думаете, что стоит раннее проверить 'if (b1 == b2) return true; '? Вероятно, 'b1 == b2' вызовет эту проблему ... – Ian

ответ

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

    Это может быть еще одной причиной проблемы ...

+0

Ранняя проверка сделала работу благодаря тысяча раз! :) – Assim

+0

@ Ассим так, это был преступник все время ...;) рад узнать, что – Ian

0

Как Ян отметил, вы должны проверить, изображения, которые вы пытаетесь сравнить в методе AreEqual() (current image и один в Rotatepacks[i]), идентичны И принадлежат к одному экземпляру или нет? ЕСЛИ они принадлежат к одному экземпляру, он, очевидно, генерирует это исключение. Используйте метод .Equals(), чтобы проверить, принадлежат ли изображения одному экземпляру.

Рассмотрим экземпляр картинку

Bitmap img;

Изображение в img загружается в поле изображения, а также в RotatePacks. В вашем коде вы пытаетесь заблокировать тот же самый экземпляр дважды, чтобы он генерировал исключение. Линии растрового изображения, которые Ian указывали, хорошо ..., 2 разных изображения могут иметь одинаковый размер и формат пикселей.

Также, если это действительно так, я не думаю, что вам нужно сравнить пиксель за пикселем. Я полагаю, что у вас есть Bitmap экземпляров в Rotatepacks. Просто сравните свой экземпляр изображения в поле с изображением с Rotatepacks, используя .Equals()

Смежные вопросы