如何解决在窗口 (WPF) 中输出位图的最佳方法是什么?
我想做什么:
给定一个简单的位图 (System.Drawing.Bitmap),我愿意将其输出到 WPF 应用程序中的窗口。我也愿意经常做,创建帧流。
我用过的:
首先,我将 Bitmap 转换为 BitmapImage,然后将其分配给 Image 控件的 Source 字段。
这种方法的问题在于转换本身。这很慢。我还没有找到一种工作速度足够快的方法,最好的方法在 640x480 位图上花费了大约 20 毫秒,这很慢。我希望找到一种方法,对于任何常见的解决方案或解决整个问题的不同方法,都可以在不到 5 毫秒的时间内完成此操作。也许,除了 Image 之外还有一个不同的控件可以与纯位图一起使用,我不需要转换。我也不依赖于使用 WPF,UWP 或新的 WinUI 3 有这个问题吗? 我已经检查过 UWP 使用 WriteableBitmap,这也需要转换,但也许还有不同的方式?
我发现了各种转换,其中一些很慢,而其中一些由于某种原因只会产生白色图像。我在下面提供了一个列表(我尝试了更多,但我不记得到底是什么):
- 使用以下方法。此转换有效,但转换 640x480 毫秒位图大约需要 20 毫秒。
public BitmapImage ToBitmapImage(Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
bitmap.Save(memory,ImageFormat.Png);
memory.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
bitmapImage.Freeze();
return bitmapImage;
}
}
-
使用 Asmak9.EssentialToolKit 库 (source),但该转换需要大约 27 毫秒,因此无法选择。
-
使用下面的方法。由于某种奇怪的原因,这个对我不起作用。它运行没有问题,但转换的结果是一个空白(白色)图像,而不是输入的内容。
private BitmapSource Convert(Bitmap bmp)
{
var bitmapData = bmp.LockBits(
new System.Drawing.Rectangle(0,bmp.Width,bmp.Height),System.Drawing.Imaging.ImageLockMode.ReadOnly,bmp.PixelFormat);
var bitmapSource = BitmapSource.Create(
bitmapData.Width,bitmapData.Height,bitmap.HorizontalResolution,bitmap.VerticalResolution,PixelFormats.Bgr24,null,bitmapData.Scan0,bitmapData.Stride * bitmapData.Height,bitmapData.Stride);
bmp.UnlockBits(bitmapData);
return bitmapSource;
}
- 使用下面的方法。这会产生与之前转换相同的结果 - 空白 BitmapImage。我也不确定这里可能会出现什么问题。
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
private BitmapSource Bitmap2BitmapImage(Bitmap bitmap)
{
IntPtr hBitmap = bitmap.GetHbitmap();
BitmapSource retval;
try
{
retval = Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,IntPtr.Zero,Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());
}
finally
{
DeleteObject(hBitmap);
}
return retval;
}
也许,最后 2 个转换更好,但它们没有正确转换,或者我做错了什么?或者一般有没有更好的方法来放弃转换步骤并直接显示位图?
解决方法
正如 Clement 上面指出的,方法 3 是最快的,但它需要两件事:
- 正确的像素格式集。
- Convert 方法应该在主线程中运行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。