我想从Image
控件内显示的图像中获取R,G和B的平均值。此图像的来源是使用this dll从网络摄像头捕获的帧。
即使我找到了一些应该能够执行此操作的功能,但它们可能是for C#
using pointers and unsafe code或for Windows Forms,而且我无法让它们与Image
一起使用控制。
我应该如何继续计算,或者至少将Image.Source
转换为Bitmap
才能使用WinForms链接中的函数?
答案 0 :(得分:3)
这是一个简单,纯粹的WPF解决方案,它直接访问BitmapSource的像素缓冲区。它适用于Bgr24
,Bgr32
,Bgra32
和Pbgra32
格式。如果Pbgra32
,所有Alpha值都应为255,否则您可能需要将每个像素(预乘)颜色值除以alpha / 255
。
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));
}
由于Image控件的Source
属性属于ImageSource
类型,因此必须先将其强制转换为BitmapSource
,然后再将其传递给方法:
var bitmap = (BitmapSource)image.Source;
var color = GetAverageColor(bitmap);
答案 1 :(得分:1)
已编辑以支持WPF图像控制(仍需要参考System.Drawing)。
Public Function GetWPFImageAverageRGB(wpfImage As System.Windows.Controls.Image) As System.Drawing.Color
Using ms = New IO.MemoryStream()
Dim encoder = New JpegBitmapEncoder()
encoder.Frames.Add(BitmapFrame.Create(CType(wpfImage.Source, BitmapImage)))
encoder.Save(ms)
Using bmp = CType(System.Drawing.Bitmap.FromStream(ms), System.Drawing.Bitmap)
Dim reds As Long
Dim greens As Long
Dim blues As Long
For x = 0 To bmp.Width - 1
For y = 0 To bmp.Height - 1
With bmp.GetPixel(x, y)
reds += .R
greens += .G
blues += .B
End With
Next
Next
Dim count = bmp.Height * bmp.Width
Return System.Drawing.Color.FromArgb(CInt(reds / count), CInt(greens / count), CInt(blues / count))
End Using
End Using
End Function
用法:
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