Wpf 从vb.net中图像控件内显示的图片中获取平均RGB值

Wpf 从vb.net中图像控件内显示的图片中获取平均RGB值,wpf,vb.net,visual-studio-2013,Wpf,Vb.net,Visual Studio 2013,我想从图像控件内显示的图像中获得R、G和B的平均值。此图像的来源是使用从网络摄像头捕获的帧 尽管我找到了一些应该能够做到这一点的函数,但它们要么是,要么是,我无法让它们与图像控件一起工作 我应该如何继续计算,或者至少将Image.Source转换为位图,以便使用WinForms链接中的函数?编辑以支持WPF图像控制仍然需要参考System.Drawing 用法: With GetWPFImageAverageRGB(image) 'image is a System.Windows.Contro

我想从图像控件内显示的图像中获得R、G和B的平均值。此图像的来源是使用从网络摄像头捕获的帧

尽管我找到了一些应该能够做到这一点的函数,但它们要么是,要么是,我无法让它们与图像控件一起工作

我应该如何继续计算,或者至少将Image.Source转换为位图,以便使用WinForms链接中的函数?

编辑以支持WPF图像控制仍然需要参考System.Drawing

用法:

With GetWPFImageAverageRGB(image) 'image is a System.Windows.Controls.image
   Console.WriteLine("Average: R={0}, G={1}, B={2}", .R, .G, .B)
   Console.ReadKey()
End With
编辑以支持WPF图像控制仍需要参考System.Drawing

用法:

With GetWPFImageAverageRGB(image) 'image is a System.Windows.Controls.image
   Console.WriteLine("Average: R={0}, G={1}, B={2}", .R, .G, .B)
   Console.ReadKey()
End With

这是一个简单、纯粹的WPF解决方案,它直接访问BitmapSource的像素缓冲区。它适用于Bgr24、Bgr32、Bgra32和Pbgra32格式。在Pbgra32的情况下,所有alpha值应为255,否则您可能必须将每个像素的预乘颜色值除以alpha/255


这是一个简单、纯粹的WPF解决方案,它直接访问BitmapSource的像素缓冲区。它适用于Bgr24、Bgr32、Bgra32和Pbgra32格式。在Pbgra32的情况下,所有alpha值应为255,否则您可能必须将每个像素的预乘颜色值除以alpha/255


@总有一天会的。谢谢克雷格。我能够从文件中获得RGB平均值,但仍然找不到使用图像控件源代码的方法。有什么建议吗?另外,就像@OneFineDay提到的,这个双循环有点慢,转换成锁位会有点太复杂吗?这样或那样,你将遍历所有字节,无论是在双循环中还是通过字节数组。GetPixel是产生任何不利成本的地方,但它仍然非常灵活。你有WPF图像元素吗?该函数只接受一个图像对象,因此它可以直接从您的元素而不是使用Drawing.Image.FromFile,是的,我也将发布一个LockBits实现。很抱歉我的坚持,但是,如果我只是尝试GetImageAverageRGBimgCapture,imgCapture是图像对象的名称,我得到的值类型为“System.Windows.Controls.Image”,无法转换为“System.Drawing.Image”。@Molx对此表示抱歉!请参见编辑。我在一个带有图像控件和加载的.PNG的WPF窗口中尝试了这一点。如果有人有一个更简单、不太迂回的方法来做这件事,我也很想知道。@gone-day,是的,会的。谢谢Craig。我能够从文件中获得RGB平均值,但仍然找不到使用图像控件源代码的方法。有什么建议吗?另外,就像@OneFineDay提到的,这个双循环有点慢,转换成锁位会有点太复杂吗?这样或那样,你将遍历所有字节,无论是在双循环中还是通过字节数组。GetPixel是产生任何不利成本的地方,但它仍然非常灵活。你有WPF图像元素吗?该函数只接受一个图像对象,因此它可以直接从您的元素而不是使用Drawing.Image.FromFile,是的,我也将发布一个LockBits实现。很抱歉我的坚持,但是,如果我只是尝试GetImageAverageRGBimgCapture,imgCapture是图像对象的名称,我得到的值类型为“System.Windows.Controls.Image”,无法转换为“System.Drawing.Image”。@Molx对此表示抱歉!请参见编辑。我在一个带有图像控件和加载的.PNG的WPF窗口中尝试了这一点。如果有人有一个更简单,不太迂回的方法来做这件事,我也想知道。这是完美的工作后,我把它翻译成VB不是一个在线工具的问题,谢谢!在我把它翻译成VB后,它工作得非常好。在线工具没有问题,谢谢!
public Color GetAverageColor(BitmapSource bitmap)
{
    var format = bitmap.Format;

    if (format != PixelFormats.Bgr24 &&
        format != PixelFormats.Bgr32 &&
        format != PixelFormats.Bgra32 &&
        format != PixelFormats.Pbgra32)
    {
        throw new InvalidOperationException("BitmapSource must have Bgr24, Bgr32, Bgra32 or Pbgra32 format");
    }

    var width = bitmap.PixelWidth;
    var height = bitmap.PixelHeight;
    var numPixels = width * height;
    var bytesPerPixel = format.BitsPerPixel / 8;
    var pixelBuffer = new byte[numPixels * bytesPerPixel];

    bitmap.CopyPixels(pixelBuffer, width * bytesPerPixel, 0);

    long blue = 0;
    long green = 0;
    long red = 0;

    for (int i = 0; i < pixelBuffer.Length; i += bytesPerPixel)
    {
        blue += pixelBuffer[i];
        green += pixelBuffer[i + 1];
        red += pixelBuffer[i + 2];
    }

    return Color.FromRgb((byte)(red / numPixels), (byte)(green / numPixels), (byte)(blue / numPixels));
}
var bitmap = (BitmapSource)image.Source; 
var color = GetAverageColor(bitmap);