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.LockBitsand copy the pixels from the BitmapSourcestraight 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

