2016-12-01 17 views
0

У меня есть изображения в градациях серого ArrayList<System.Windows.Controls.Image>, выложенные горизонтально на Canvas. Их ImageSource имеют тип System.Windows.Media.Imaging.BitmapImage.Получите оттенки серого Высота изображения без учета белых пикселей

Есть ли способ измерения в пикселях высоты каждого Imageбез учета белых непрозрачных пикселей За пределами цветной части?

Скажем, у меня есть Image высоты 10, в которой вся верхняя половина белая, а нижняя половина - черная; Мне нужно было бы получить 5, так как это высота. Точно так же, если у Image была верхняя третья черная, средняя третья белая и нижняя третья черная, высота была бы 10.

Вот рисунок, который показывает желательную высоту (в синем) из 3-х изображений:

Example picture

Я готов использовать другой тип для изображений, но это должно быть возможным либо получить от byte[], или преобразовать Image в него.

Я прочитал документы на Image, ImageSource и Visual, но я действительно не знаю, с чего начать.

+0

Вы собираетесь хотите создать гистограмму строк изображения, а затем проанализировать гистограмму, чтобы найти границы небелых пикселов. – Abion47

+0

@ Abion47 Если я могу получить гистограмму, я могу, возможно, просто получить и добавить RGB в каждой строке, чтобы увидеть, все ли это белое. Но как я могу получить такие данные? – Mat

+0

Это зависит от того, какой тип объекта «Source» для ваших элементов управления Image. – Abion47

ответ

1

Доступ к данным о пикселях из BitmapImage - это немного хлопот, но вы можете построить WriteableBitmap из объекта BitmapImage, что намного проще (не говоря уже о более эффективном).

WriteableBitmap bmp = new WriteableBitmap(img.Source as BitmapImage); 
bmp.Lock(); 

unsafe 
{ 
    int width = bmp.PixelWidth; 
    int height = bmp.PixelHeight; 
    byte* ptr = (byte*)bmp.BackBuffer; 
    int stride = bmp.BackBufferStride; 
    int bpp = 4; // Assuming Bgra image format 

    int hms; 
    for (int y = 0; y < height; y++) 
    { 
     hms = y * stride; 
     for (int x = 0; x < width; x++) 
     { 
      int idx = hms + (x * bpp); 

      byte b = ptr[idx]; 
      byte g = ptr[idx + 1]; 
      byte r = ptr[idx + 2]; 
      byte a = ptr[idx + 3]; 

      // Construct your histogram 
     } 
    } 
} 

bmp.Unlock(); 

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

EDIT: Вот Silverlight решение:

public static int getNonWhiteHeight(this Image img) 
{ 
    WriteableBitmap bmp = new WriteableBitmap(img.Source as BitmapImage); 
    int topWhiteRowCount = 0; 
    int width = bmp.PixelWidth; 
    int height = bmp.PixelHeight; 

    for (int y = 0; y < height; y++) 
    { 
     for (int x = 0; x < width; x++) 
     { 
      int pixel = bmp.Pixels[y * width + x]; 
      if (pixel != -1) 
      { 
       topWhiteRowCount = y - 1; 
       goto returnLbl; 
      } 
     } 
    } 

    returnLbl: 
    return topWhiteRowCount >= 0 ? height - topWhiteRowCount : height; 
} 
+0

Хмм, это дает мне несколько важных компиляционных ошибок, таких как: ' Небезопасный код может появляться только при компиляции с/unsafe' и 'WriteableBitmap не содержит общедоступных определение для 'Lock'' (То же самое для 'BackBuffer' и' BackBufferStride') – Mat

+0

Я могу активировать небезопасную компиляцию, но для последней ошибки я не знаю, как исправить. Вы уверены, что совместимы с Silverlight? – Mat

+1

@Mat Я не видел, что вы использовали Silverlight, мои извинения. У меня нет большого опыта работы с Silverlight, но похоже, что рекомендуемый подход состоит в том, чтобы по-прежнему создавать «WriteableBitmap», но вместо этого ссылаться на [Pixels] (https://msdn.microsoft.com/en-us /library/system.windows.media.imaging.writeablebitmap.pixels(v=vs.95).aspx). (И нет, это не требует использования 'unsafe'.) – Abion47

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

  • Нет связанных вопросов^_^