2017-09-30 6 views

Répondre

1

Ce que vous pouvez faire est de créer une classe dérivée personnalisée à partir de BitmapSource de WPF.

Par exemple, pour ce XAML:

<Window x:Class="SharpDXWpfApp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Image Name="MyImage"></Image> 
    </Grid> 
</Window> 

Ce code de fenêtre utilise une coutume "WicBitmapSource".

public partial class MainWindow : Window 
{ 
    private WicBitmapSource _bmp; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     _bmp = new WicBitmapSource(@"c:\path\killroy_was_here.png"); 
     MyImage.Source = _bmp; 
    } 

    protected override void OnClosed(EventArgs e) 
    { 
     _bmp.Dispose(); 
    } 
} 

Voici quelques exemples de code pour cette SharpDX/Wic BitmapSource personnalisé (certaines informations sont saisies d'ici: https://blogs.msdn.microsoft.com/dwayneneed/2008/06/20/implementing-a-custom-bitmapsource/).

public class WicBitmapSource : System.Windows.Media.Imaging.BitmapSource, IDisposable 
{ 
    public WicBitmapSource(string filePath) 
    { 
     if (filePath == null) 
      throw new ArgumentNullException(nameof(filePath)); 

     using (var fac = new ImagingFactory()) 
     { 
      using (var dec = new SharpDX.WIC.BitmapDecoder(fac, filePath, DecodeOptions.CacheOnDemand)) 
      { 
       Frame = dec.GetFrame(0); 
      } 
     } 
    } 

    public WicBitmapSource(BitmapFrameDecode frame) 
    { 
     if (frame == null) 
      throw new ArgumentNullException(nameof(frame)); 

     Frame = frame; 
    } 

    public BitmapFrameDecode Frame { get; } 
    public override int PixelWidth => Frame.Size.Width; 
    public override int PixelHeight => Frame.Size.Height; 
    public override double Height => PixelHeight; 
    public override double Width => PixelWidth; 

    public override double DpiX 
    { 
     get 
     { 
      Frame.GetResolution(out double dpix, out double dpiy); 
      return dpix; 
     } 
    } 

    public override double DpiY 
    { 
     get 
     { 
      Frame.GetResolution(out double dpix, out double dpiy); 
      return dpiy; 
     } 
    } 

    public override System.Windows.Media.PixelFormat Format 
    { 
     get 
     { 
      // this is a hack as PixelFormat is not public... 
      // it would be better to do proper matching 
      var ct = typeof(System.Windows.Media.PixelFormat).GetConstructor(
       BindingFlags.Instance | BindingFlags.NonPublic, 
       null, 
       new[] { typeof(Guid) }, 
       null); 
      return (System.Windows.Media.PixelFormat)ct.Invoke(new object[] { Frame.PixelFormat }); 
     } 
    } 

    // mostly for GIFs support (indexed palette of 256 colors) 
    public override BitmapPalette Palette 
    { 
     get 
     { 
      using (var fac = new ImagingFactory()) 
      { 
       var palette = new Palette(fac); 
       try 
       { 
        Frame.CopyPalette(palette); 
       } 
       catch 
       { 
        // no indexed palette (PNG, JPG, etc.) 
        // it's a pity SharpDX throws here, 
        // it would be better to return null more gracefully as this is not really an error 
        // if you only want to support non indexed palette images, just return null for the property w/o trying to get a palette 
        return null; 
       } 

       var list = new List<Color>(); 
       foreach (var c in palette.GetColors<int>()) 
       { 
        var bytes = BitConverter.GetBytes(c); 
        var color = Color.FromArgb(bytes[3], bytes[2], bytes[1], bytes[0]); 
        list.Add(color); 
       } 
       return new BitmapPalette(list); 
      } 
     } 
    } 

    public override void CopyPixels(Int32Rect sourceRect, Array pixels, int stride, int offset) 
    { 
     if (offset != 0) 
      throw new NotSupportedException(); 

     Frame.CopyPixels(
      new SharpDX.Mathematics.Interop.RawRectangle(sourceRect.X, sourceRect.Y, sourceRect.Width, sourceRect.Height), 
      (byte[])pixels, stride); 
    } 

    public void Dispose() => Frame.Dispose(); 

    public override event EventHandler<ExceptionEventArgs> DecodeFailed; 
    public override event EventHandler DownloadCompleted; 
    public override event EventHandler<ExceptionEventArgs> DownloadFailed; 
    public override event EventHandler<DownloadProgressEventArgs> DownloadProgress; 

    protected override Freezable CreateInstanceCore() => throw new NotImplementedException(); 
} 
+0

Merci, mais est-ce que '' devrait être un 'WicBitmapSource' à la place? –

+0

L'image est le FrameworkFrench WPF standard qui peut afficher une instance BitmapSource, quel que soit le type de cette BitmapSource. –

+0

Merci, cela fonctionne. Maintenant, est-il possible d'éviter les étapes de codage-décodage? –