C# 在 BitmapSource 和 Bitmap 之间转换有什么好方法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2284353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a good way to convert between BitmapSource and Bitmap?
提问by JohannesH
As far as I can tell the only way to convert from BitmapSource to Bitmap is through unsafe code... Like this (from Lesters WPF blog):
据我所知,从 BitmapSource 转换为 Bitmap 的唯一方法是通过不安全的代码......像这样(来自Lesters WPF 博客):
myBitmapSource.CopyPixels(bits, stride, 0);
unsafe
{
fixed (byte* pBits = bits)
{
IntPtr ptr = new IntPtr(pBits);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(
width,
height,
stride,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb,ptr);
return bitmap;
}
}
To do the reverse:
反过来做:
System.Windows.Media.Imaging.BitmapSource bitmapSource =
System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bitmap.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
Is there an easier way in the framework? And what is the reason it isn't in there (if it's not)? I would think it's fairly usable.
框架中有更简单的方法吗?它不在那里的原因是什么(如果不是)?我觉得还是蛮好用的。
The reason I need it is because I use AForge to do certain image operations in an WPF app. WPF wants to show BitmapSource/ImageSource but AForge works on Bitmaps.
我需要它的原因是因为我使用 AForge 在 WPF 应用程序中执行某些图像操作。WPF 想要显示 BitmapSource/ImageSource,但 AForge 可以处理位图。
采纳答案by josef.axa
It is possible to do without using unsafe code by using Bitmap.LockBits
and copy the pixels from the BitmapSource
straight to the Bitmap
通过使用Bitmap.LockBits
和复制像素从BitmapSource
直线到Bitmap
Bitmap GetBitmap(BitmapSource source) {
Bitmap bmp = new Bitmap(
source.PixelWidth,
source.PixelHeight,
PixelFormat.Format32bppPArgb);
BitmapData data = bmp.LockBits(
new Rectangle(Point.Empty, bmp.Size),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppPArgb);
source.CopyPixels(
Int32Rect.Empty,
data.Scan0,
data.Height * data.Stride,
data.Stride);
bmp.UnlockBits(data);
return bmp;
}
回答by caesay
Is this what your looking for?
这是您要找的吗?
Bitmap bmp = System.Drawing.Image.FromHbitmap(pBits);
回答by melvas
You can just use these two methods:
你可以只使用这两种方法:
public static BitmapSource ConvertBitmap(Bitmap source)
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
source.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
Bitmap bitmap;
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
bitmap = new Bitmap(outStream);
}
return bitmap;
}
It works perfectly for me.
它非常适合我。
回答by user3318309
Here a code to set transparent background to any bitmap resource within a Resource Dictionary (not Resources.resx often used in Windows.Forms age). I call this methode before InitializeComponent() - methode. The methodes 'ConvertBitmap(Bitmap source)' and BitmapFromSource(BitmapSource bitmapsource) are mentioned in post from melvas above.
这里是为资源字典中的任何位图资源设置透明背景的代码(不是在 Windows.Forms 时代经常使用的 Resources.resx)。我在 InitializeComponent() - methode 之前调用此方法。上面 melvas 的帖子中提到了方法 'ConvertBitmap(Bitmap source)' 和 BitmapFromSource(BitmapSource bitmapsource)。
private void SetBitmapResourcesTransparent()
{
Image img;
BitmapSource bmpSource;
System.Drawing.Bitmap bmp;
foreach (ResourceDictionary resdict in Application.Current.Resources.MergedDictionaries)
{
foreach (DictionaryEntry dictEntry in resdict)
{
// search for bitmap resource
if ((img = dictEntry.Value as Image) is Image
&& (bmpSource = img.Source as BitmapSource) is BitmapSource
&& (bmp = BitmapFromSource(bmpSource)) != null)
{
// make bitmap transparent and assign it back to ressource
bmp.MakeTransparent(System.Drawing.Color.Magenta);
bmpSource = ConvertBitmap(bmp);
img.Source = bmpSource;
}
}
}
}
回答by Mauro Sampietro
This is neat and faster than light:
这比光还快:
return Imaging.CreateBitmapSourceFromHBitmap( bitmap.GetHbitmap(), IntPtr.Zero,
Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions() );
回答by Andreas
You can share the pixeldata between both namespaces. You don't have to convert.
您可以在两个命名空间之间共享像素数据。你不必转换。
Use the SharedBitmapSource. https://stackoverflow.com/a/32841840/690656
使用 SharedBitmapSource。https://stackoverflow.com/a/32841840/690656