28 votes

Convertir System.Drawing.Icon en System.Media.ImageSource

J'ai un IntPtr transporté à travers une frontière non gérée/gérée qui correspond à un Handle d'icône. La conversion en une icône est triviale via la méthode FromHandle(), et cela était satisfaisant jusqu'à récemment.

En fait, j'ai suffisamment de fils étranges pour que la danse MTA/STA à laquelle je me livrais pour empêcher un WinForm hébergé de casser l'interface principale (WPF-tastique) de l'application soit trop fragile pour être maintenue. Le WinForm doit donc disparaître.

Alors, comment puis-je obtenir une version ImageSource d'une icône ?

Remarque, j'ai essayé ImageSourceConverter sans succès.

En passant, je peux obtenir la ressource sous-jacente pour un peu de mais pas toutes les icônes concernées et elles existent généralement en dehors de l'assemblage de mon application (en fait, elles existent souvent dans des dll non gérées).

55voto

Byte Points 348

Méthode de conversion simple sans création d'objets supplémentaires :

    public static ImageSource ToImageSource(this Icon icon)
    {
        ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(
            icon.Handle,
            Int32Rect.Empty,
            BitmapSizeOptions.FromEmptyOptions());

        return imageSource;
    }

36voto

Kenan E. K. Points 8497

Essayez ça :

Icon img;

Bitmap bitmap = img.ToBitmap();
IntPtr hBitmap = bitmap.GetHbitmap();

ImageSource wpfBitmap =
     Imaging.CreateBitmapSourceFromHBitmap(
          hBitmap, IntPtr.Zero, Int32Rect.Empty, 
          BitmapSizeOptions.FromEmptyOptions());

UPDATE : Incorporer la suggestion d'Alex et en faire une méthode d'extension :

internal static class IconUtilities
{
    [DllImport("gdi32.dll", SetLastError = true)]
    private static extern bool DeleteObject(IntPtr hObject);

    public static ImageSource ToImageSource(this Icon icon)
    {            
        Bitmap bitmap = icon.ToBitmap();
        IntPtr hBitmap = bitmap.GetHbitmap();

        ImageSource wpfBitmap = Imaging.CreateBitmapSourceFromHBitmap(
            hBitmap,
            IntPtr.Zero,
            Int32Rect.Empty,
            BitmapSizeOptions.FromEmptyOptions());

        if (!DeleteObject(hBitmap))
        {
            throw new Win32Exception();
        }

        return wpfBitmap;
    }
}

Alors vous pouvez le faire :

ImageSource wpfBitmap = img.ToImageSource();

9voto

Darren Points 160
MemoryStream iconStream = new MemoryStream();
myForm.Icon.Save(iconStream);
iconStream.Seek(0, SeekOrigin.Begin);
_wpfForm.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconStream);

8voto

Derek Bartram Points 61

Lors de l'utilisation de flux jetables, il est presque toujours recommandé d'utiliser des blocs "using" pour forcer la libération correcte des ressources.

using (MemoryStream iconStream = new MemoryStream())
{
   icon.Save(iconStream);
   iconStream.Seek(0, SeekOrigin.Begin);

   this.TargetWindow.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconStream);
}

icon est la source System.Drawing.Icon, et this.TargetWindow est la cible System.Windows.Window.

1voto

Justin Davis Points 11

En m'inspirant de ce qui précède, j'ai créé des icônes de la plus haute qualité pour moi-même. Chargement des icônes à partir d'un tableau d'octets. J'utilise le cache au chargement parce que si vous ne le faites pas, vous obtiendrez une exception lorsque vous disposerez du flux de mémoire.

   internal static ImageSource ToImageSource(this byte[] iconBytes)
    {
        if (iconBytes == null)
            throw new ArgumentNullException(nameof(iconBytes));
        using (var ms = new MemoryStream(iconBytes))
        {
            return BitmapFrame.Create(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
        }
    }

Prograide.com

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.

Powered by:

X