在不考虑白色像素的情况下获取灰度图像高度

Get grayscale Image height without considering white pixels

我有一个 ArrayList<System.Windows.Controls.Image> 的灰度图片水平放置在 Canvas 上。他们的 ImageSource 属于 System.Windows.Media.Imaging.BitmapImage.

类型

有没有办法以像素为单位测量每个 Image 的高度而不考虑彩色部分外的白色、非透明像素

假设我有一个 Image 高度 10,其中整个上半部分是白色的,下半部分是黑色的;我需要得到 5 因为它的高度。同理,如果Image上三分之一黑,中三分之一白,下三分之一黑,那么高度就是10.

这是一张显示 3 张图片所需高度(蓝色)的图:

我愿意为图像使用另一种类型,但必须可以从 byte[] 数组获取该类型,或者将 Image 转换为该类型。

我已经阅读了 ImageImageSourceVisual 上的文档,但我真的不知道从哪里开始。

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