// Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; using System.IO; using Avalonia.Win32.Interop; using SharpDX.WIC; using APixelFormat = Avalonia.Platform.PixelFormat; using D2DBitmap = SharpDX.Direct2D1.Bitmap; namespace Avalonia.Direct2D1.Media { /// /// A WIC implementation of a . /// public class WicBitmapImpl : BitmapImpl { /// /// Initializes a new instance of the class. /// /// The filename of the bitmap to load. public WicBitmapImpl(string fileName) { using (BitmapDecoder decoder = new BitmapDecoder(Direct2D1Platform.ImagingFactory, fileName, DecodeOptions.CacheOnDemand)) { WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, decoder.GetFrame(0), BitmapCreateCacheOption.CacheOnDemand); } } /// /// Initializes a new instance of the class. /// /// The stream to read the bitmap from. public WicBitmapImpl(Stream stream) { using (BitmapDecoder decoder = new BitmapDecoder(Direct2D1Platform.ImagingFactory, stream, DecodeOptions.CacheOnLoad)) { WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, decoder.GetFrame(0), BitmapCreateCacheOption.CacheOnLoad); } } /// /// Initializes a new instance of the class. /// /// The width of the bitmap. /// The height of the bitmap. /// Pixel format public WicBitmapImpl(int width, int height, APixelFormat? pixelFormat = null) { if (!pixelFormat.HasValue) { pixelFormat = APixelFormat.Bgra8888; } PixelFormat = pixelFormat; WicImpl = new Bitmap( Direct2D1Platform.ImagingFactory, width, height, pixelFormat.Value.ToWic(), BitmapCreateCacheOption.CacheOnLoad); } public WicBitmapImpl(APixelFormat format, IntPtr data, int width, int height, int stride) { WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, width, height, format.ToWic(), BitmapCreateCacheOption.CacheOnDemand); PixelFormat = format; using (var l = WicImpl.Lock(BitmapLockFlags.Write)) { for (var row = 0; row < height; row++) { UnmanagedMethods.CopyMemory( (l.Data.DataPointer + row * l.Stride), (data + row * stride), (UIntPtr) l.Data.Pitch); } } } protected APixelFormat? PixelFormat { get; } /// /// Gets the width of the bitmap, in pixels. /// public override int PixelWidth => WicImpl.Size.Width; /// /// Gets the height of the bitmap, in pixels. /// public override int PixelHeight => WicImpl.Size.Height; public override void Dispose() { WicImpl.Dispose(); } /// /// Gets the WIC implementation of the bitmap. /// public Bitmap WicImpl { get; } /// /// Gets a Direct2D bitmap to use on the specified render target. /// /// The render target. /// The Direct2D bitmap. public override OptionalDispose GetDirect2DBitmap(SharpDX.Direct2D1.RenderTarget renderTarget) { FormatConverter converter = new FormatConverter(Direct2D1Platform.ImagingFactory); converter.Initialize(WicImpl, SharpDX.WIC.PixelFormat.Format32bppPBGRA); return new OptionalDispose(D2DBitmap.FromWicBitmap(renderTarget, converter), true); } public override void Save(Stream stream) { using (var encoder = new PngBitmapEncoder(Direct2D1Platform.ImagingFactory, stream)) using (var frame = new BitmapFrameEncode(encoder)) { frame.Initialize(); frame.WriteSource(WicImpl); frame.Commit(); encoder.Commit(); } } } }