Mat
Mat

Reputation: 1500

Get grayscale Image height without considering white pixels

I have grayscale pictures of an ArrayList<System.Windows.Controls.Image> laid out horizontally on a Canvas. Their ImageSource are of type System.Windows.Media.Imaging.BitmapImage.

Is there a way to measure in pixels the height of each Image without considering white, non-transparent pixels Outside the colored part ?

Lets say I have an Image of height 10, in which the whole top half is white and the bottom half is black; I would need to get 5 as it's height. In the same way, if that Image had the top third black, middle third white and bottom third black, the height would be 10.

Here's a drawing that shows the desired heights (in blue) of 3 images:

Example picture

I am willing to use another type for the images, but it Must be possible to either get from a byte[] array to that type, or to convert Image to it.

I have read the docs on Image, ImageSource and Visual, but I really have no clue where to start.

Upvotes: 0

Views: 262

Answers (1)

Abion47
Abion47

Reputation: 24726

Accessing pixel data from a BitmapImage is a bit of a hassle, but you can construct a WriteableBitmap from the BitmapImage object which is much easier (not to mention more efficient).

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

From here, you can construct a histogram from the pixel data, and analyze that histogram to find the boundaries of the non-white pixels in the images.

EDIT: Here's a Silverlight solution:

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

Upvotes: 1

Related Questions