我在ArrayList<System.Windows.Controls.Image>
水平放置了Canvas
的灰度图片。他们的ImageSource
类型为System.Windows.Media.Imaging.BitmapImage
。
有没有办法以像素为单位测量每个Image
的高度,而不考虑彩色部分外的白色,非透明像素?
假设我有Image
身高10
,其中整个上半部分是白色,下半部分是黑色;我需要得到5
作为它的高度。同样地,如果Image
具有前三分之一黑色,中间三分之一白色和底部三分之一黑色,则高度将为10
。
这是一张图,显示了3幅图像所需的高度(蓝色):
我愿意为图片使用其他类型,但必须可以从byte[]
数组获取该类型,或将Image
转换为该类型。
我已阅读Image
,ImageSource
和Visual
上的文档,但我真的不知道从哪里开始。
答案 0 :(得分:1)
从BitmapImage访问像素数据有点麻烦,但你可以从BitmapImage对象构造一个WriteableBitmap,这样更容易(更不用说效率更高)。
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();
从这里,您可以根据像素数据构建直方图,并分析该直方图以查找图像中非白色像素的边界。
编辑:这是一个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;
}