BitmapImpl.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright (c) The Perspex Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.IO;
  5. using Perspex.Platform;
  6. using SharpDX.WIC;
  7. namespace Perspex.Direct2D1.Media
  8. {
  9. /// <summary>
  10. /// A Direct2D implementation of a <see cref="Perspex.Media.Imaging.Bitmap"/>.
  11. /// </summary>
  12. public class BitmapImpl : IBitmapImpl
  13. {
  14. private readonly ImagingFactory _factory;
  15. private SharpDX.Direct2D1.Bitmap _direct2D;
  16. /// <summary>
  17. /// Initializes a new instance of the <see cref="BitmapImpl"/> class.
  18. /// </summary>
  19. /// <param name="factory">The WIC imaging factory to use.</param>
  20. /// <param name="fileName">The filename of the bitmap to load.</param>
  21. public BitmapImpl(ImagingFactory factory, string fileName)
  22. {
  23. _factory = factory;
  24. using (BitmapDecoder decoder = new BitmapDecoder(factory, fileName, DecodeOptions.CacheOnDemand))
  25. {
  26. WicImpl = new Bitmap(factory, decoder.GetFrame(0), BitmapCreateCacheOption.CacheOnDemand);
  27. }
  28. }
  29. /// <summary>
  30. /// Initializes a new instance of the <see cref="BitmapImpl"/> class.
  31. /// </summary>
  32. /// <param name="factory">The WIC imaging factory to use.</param>
  33. /// <param name="stream">The stream to read the bitmap from.</param>
  34. public BitmapImpl(ImagingFactory factory, Stream stream)
  35. {
  36. _factory = factory;
  37. using (BitmapDecoder decoder = new BitmapDecoder(factory, stream, DecodeOptions.CacheOnLoad))
  38. {
  39. WicImpl = new Bitmap(factory, decoder.GetFrame(0), BitmapCreateCacheOption.CacheOnLoad);
  40. }
  41. }
  42. /// <summary>
  43. /// Initializes a new instance of the <see cref="BitmapImpl"/> class.
  44. /// </summary>
  45. /// <param name="factory">The WIC imaging factory to use.</param>
  46. /// <param name="width">The width of the bitmap.</param>
  47. /// <param name="height">The height of the bitmap.</param>
  48. public BitmapImpl(ImagingFactory factory, int width, int height)
  49. {
  50. _factory = factory;
  51. WicImpl = new Bitmap(
  52. factory,
  53. width,
  54. height,
  55. PixelFormat.Format32bppPBGRA,
  56. BitmapCreateCacheOption.CacheOnLoad);
  57. }
  58. /// <summary>
  59. /// Gets the width of the bitmap, in pixels.
  60. /// </summary>
  61. public int PixelWidth => WicImpl.Size.Width;
  62. /// <summary>
  63. /// Gets the height of the bitmap, in pixels.
  64. /// </summary>
  65. public int PixelHeight => WicImpl.Size.Height;
  66. public virtual void Dispose()
  67. {
  68. WicImpl.Dispose();
  69. }
  70. /// <summary>
  71. /// Gets the WIC implementation of the bitmap.
  72. /// </summary>
  73. public Bitmap WicImpl
  74. {
  75. get; }
  76. /// <summary>
  77. /// Gets a Direct2D bitmap to use on the specified render target.
  78. /// </summary>
  79. /// <param name="renderTarget">The render target.</param>
  80. /// <returns>The Direct2D bitmap.</returns>
  81. public SharpDX.Direct2D1.Bitmap GetDirect2DBitmap(SharpDX.Direct2D1.RenderTarget renderTarget)
  82. {
  83. if (_direct2D == null)
  84. {
  85. FormatConverter converter = new FormatConverter(_factory);
  86. converter.Initialize(WicImpl, PixelFormat.Format32bppPBGRA);
  87. _direct2D = SharpDX.Direct2D1.Bitmap.FromWicBitmap(renderTarget, converter);
  88. }
  89. return _direct2D;
  90. }
  91. /// <summary>
  92. /// Saves the bitmap to a file.
  93. /// </summary>
  94. /// <param name="fileName">The filename.</param>
  95. public void Save(string fileName)
  96. {
  97. if (Path.GetExtension(fileName) != ".png")
  98. {
  99. // Yeah, we need to support other formats.
  100. throw new NotSupportedException("Use PNG, stoopid.");
  101. }
  102. using (FileStream s = new FileStream(fileName, FileMode.Create))
  103. {
  104. PngBitmapEncoder encoder = new PngBitmapEncoder(_factory);
  105. encoder.Initialize(s);
  106. BitmapFrameEncode frame = new BitmapFrameEncode(encoder);
  107. frame.Initialize();
  108. frame.WriteSource(WicImpl);
  109. frame.Commit();
  110. encoder.Commit();
  111. }
  112. }
  113. }
  114. }