c# - ¿Hay una buena forma de convertir BitmapSource a Bitmap?
.net wpf (6)
¿Es esto lo que estás buscando?
Bitmap bmp = System.Drawing.Image.FromHbitmap(pBits);
Por lo que puedo decir, la única forma de convertir de BitmapSource a Bitmap es a través de un código inseguro ... Como este (del blog 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;
}
}
Para hacer lo contrario:
System.Windows.Media.Imaging.BitmapSource bitmapSource =
System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bitmap.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
¿Hay alguna manera más fácil en el marco? ¿Y cuál es la razón por la que no está ahí (si no es así)? Creo que es bastante utilizable.
La razón por la que lo necesito es porque uso AForge para realizar ciertas operaciones de imagen en una aplicación WPF. WPF quiere mostrar BitmapSource / ImageSource pero AForge funciona en Bitmaps.
Aquí un código para establecer el fondo transparente a cualquier recurso de mapa de bits dentro de un Diccionario de recursos (no Resources.resx a menudo utilizado en Windows.Versiones de edad). Llamo a este método antes de InitializeComponent () - method. El ConvertBitmap de los metodos (fuente de mapa de bits) y BitmapFromSource (bitmapsource de BitmapSource) se mencionan en las publicaciones anteriores de melvas.
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;
}
}
}
}
Es posible prescindir de un código no seguro utilizando Bitmap.LockBits
y copiar los píxeles de BitmapSource
directamente en el 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;
}
Esto es limpio y más rápido que la luz:
return Imaging.CreateBitmapSourceFromHBitmap( bitmap.GetHbitmap(), IntPtr.Zero,
Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions() );
Puede compartir los datos de píxeles entre ambos espacios de nombres. No tienes que convertir
Use SharedBitmapSource. https://.com/a/32841840/690656
Puedes usar estos dos métodos:
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;
}
Funciona perfectamente para mí.