2016-12-01 2 views
0

J'ai des images en niveaux de gris d'un ArrayList<System.Windows.Controls.Image> disposées horizontalement sur un Canvas. Leurs ImageSource sont de type System.Windows.Media.Imaging.BitmapImage.Obtenir une échelle de gris Hauteur de l'image sans tenir compte des pixels blancs

Existe-t-il un moyen de mesurer en pixels la hauteur de chaque Imagesans tenir compte des pixels blancs et non transparents? En dehors de la partie colorée? Disons que j'ai une Image de hauteur 10, dans laquelle toute la moitié supérieure est blanche et la moitié inférieure est noire; Je devrais obtenir 5 car c'est la taille. De la même manière, si ce Image avait le tiers supérieur noir, le tiers moyen blanc et le tiers inférieur noir, la hauteur serait 10.

est ici un dessin qui montre les hauteurs souhaitées (en bleu) de 3 images:

Example picture

Je suis prêt à utiliser un autre type pour les images, mais il doit être possible d'obtenir soit d'un byte[] pour ce type, ou pour y convertir Image. J'ai lu les documents sur Image, ImageSource et Visual, mais je n'ai vraiment aucune idée par où commencer.

+0

Vous allez vouloir générer un histogramme pour les lignes de l'image, puis d'analyser l'histogramme pour trouver les limites des pixels non blancs. – Abion47

+0

@ Abion47 Si je peux obtenir un histogramme, je peux probablement aussi simplement obtenir et ajouter le RVB sur chaque ligne pour voir si tout est blanc. Mais comment puis-je même obtenir de telles données? – Mat

+0

Cela dépend du type d'objet que les contrôles 'Source' pour vos images sont. – Abion47

Répondre

1

Accéder à des données de pixel à partir d'un bitmapImage est un peu compliqué, mais vous pouvez construire un WriteableBitmap à partir de l'objet BitmapImage, ce qui est beaucoup plus facile (pour ne pas dire plus efficace).

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

A partir de là, on peut construire un histogramme à partir des données de pixels, et d'analyser que l'histogramme pour trouver les limites des pixels non blancs dans les images.

EDIT: Voici une solution 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

Hmm, cela me donne quelques erreurs de compilation importantes telles que: ' code dangereux peut apparaître seulement si la compilation avec/unsafe' et 'WriteableBitmap ne contient pas un public définition pour 'Lock'' (Même chose pour 'BackBuffer' et' BackBufferStride') – Mat

+0

Je peux activer la compilation dangereuse, mais pour la dernière erreur je ne sais pas comment réparer. Êtes-vous sûr que c'est compatible avec Silverlight? – Mat

+1

@Mat Je n'ai pas vu que vous utilisiez Silverlight, mes excuses. Je n'ai pas beaucoup d'expérience avec Silverlight, mais il semble que l'approche recommandée est de toujours créer le 'WriteableBitmap', mais référence à la place [Pixels] (https://msdn.microsoft.com/fr-fr /library/system.windows.media.imaging.writeablebitmap.pixels(v=vs.95).aspx) propriété. (Et non, cela ne nécessite pas d'être «dangereux» pour être utilisé.) – Abion47