Is there a good way to convert between BitmapSource and Bitmap?
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):
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.
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 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;
}
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.
Is this what your looking for?
Bitmap bmp = System.Drawing.Image.FromHbitmap(pBits);
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.
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;
}
}
}
}
This is neat and faster than light:
return Imaging.CreateBitmapSourceFromHBitmap( bitmap.GetHbitmap(), IntPtr.Zero,
Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions() );
You can share the pixeldata between both namespaces. You don't have to convert.
Use the SharedBitmapSource. https://stackoverflow.com/a/32841840/690656
精彩评论