J'ai une instance de System.Drawing.Bitmap
et je voudrais la rendre disponible pour mon application WPF sous la forme d'un System.Windows.Media.Imaging.BitmapImage
.
Quelle serait la meilleure approche pour cela?
J'ai une instance de System.Drawing.Bitmap
et je voudrais la rendre disponible pour mon application WPF sous la forme d'un System.Windows.Media.Imaging.BitmapImage
.
Quelle serait la meilleure approche pour cela?
Pourquoi ne pas le charger depuis MemoryStream?
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();
}
Je sais que cela a été répondu, mais voici quelques méthodes d'extension (pour .NET 3.0+) qui effectuent la conversion. :)
/// <summary>
/// Converts a <see cref="System.Drawing.Image"/> into a WPF <see cref="BitmapSource"/>.
/// </summary>
/// <param name="source">The source image.</param>
/// <returns>A BitmapSource</returns>
public static BitmapSource ToBitmapSource(this System.Drawing.Image source)
{
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(source);
var bitSrc = bitmap.ToBitmapSource();
bitmap.Dispose();
bitmap = null;
return bitSrc;
}
/// <summary>
/// Converts a <see cref="System.Drawing.Bitmap"/> into a WPF <see cref="BitmapSource"/>.
/// </summary>
/// <remarks>Uses GDI to do the conversion. Hence the call to the marshalled DeleteObject.
/// </remarks>
/// <param name="source">The source bitmap.</param>
/// <returns>A BitmapSource</returns>
public static BitmapSource ToBitmapSource(this System.Drawing.Bitmap source)
{
BitmapSource bitSrc = null;
var hBitmap = source.GetHbitmap();
try
{
bitSrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
catch (Win32Exception)
{
bitSrc = null;
}
finally
{
NativeMethods.DeleteObject(hBitmap);
}
return bitSrc;
}
et la classe NativeMethods (pour apaiser FxCop)
/// <summary>
/// FxCop requires all Marshalled functions to be in a class called NativeMethods.
/// </summary>
internal static class NativeMethods
{
[DllImport("gdi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeleteObject(IntPtr hObject);
}
Il m'a fallu du temps pour que la conversion fonctionne dans les deux sens, alors voici les deux méthodes d'extension que j'ai trouvées:
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Media.Imaging;
public static class BitmapConversion {
public static Bitmap ToWinFormsBitmap(this BitmapSource bitmapsource) {
using (MemoryStream stream = new MemoryStream()) {
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(stream);
using (var tempBitmap = new Bitmap(stream)) {
// According to MSDN, one "must keep the stream open for the lifetime of the Bitmap."
// So we return a copy of the new bitmap, allowing us to dispose both the bitmap and the stream.
return new Bitmap(tempBitmap);
}
}
}
public static BitmapSource ToWpfBitmap(this Bitmap bitmap) {
using (MemoryStream stream = new MemoryStream()) {
bitmap.Save(stream, ImageFormat.Bmp);
stream.Position = 0;
BitmapImage result = new BitmapImage();
result.BeginInit();
// According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
// Force the bitmap to load right now so we can dispose the stream.
result.CacheOption = BitmapCacheOption.OnLoad;
result.StreamSource = stream;
result.EndInit();
result.Freeze();
return result;
}
}
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.