Reputation: 1500
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:
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
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