BitmapTests.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (c) The Avalonia 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 System.Runtime.InteropServices;
  6. using Avalonia.Controls;
  7. using Avalonia.Controls.Platform.Surfaces;
  8. using Avalonia.Controls.Shapes;
  9. using Avalonia.Layout;
  10. using Avalonia.Media;
  11. using Avalonia.Media.Imaging;
  12. using Avalonia.Platform;
  13. using Xunit;
  14. #if AVALONIA_CAIRO
  15. namespace Avalonia.Cairo.RenderTests.Media
  16. #elif AVALONIA_SKIA
  17. namespace Avalonia.Skia.RenderTests
  18. #else
  19. namespace Avalonia.Direct2D1.RenderTests.Media
  20. #endif
  21. {
  22. public class BitmapTests : TestBase
  23. {
  24. public BitmapTests()
  25. : base(@"Media\Bitmap")
  26. {
  27. Directory.CreateDirectory(OutputPath);
  28. }
  29. class Framebuffer : ILockedFramebuffer, IFramebufferPlatformSurface
  30. {
  31. public Framebuffer(PixelFormat fmt, int width, int height)
  32. {
  33. Format = fmt;
  34. var bpp = fmt == PixelFormat.Rgb565 ? 2 : 4;
  35. Width = width;
  36. Height = height;
  37. RowBytes = bpp * width;
  38. Address = Marshal.AllocHGlobal(Height * RowBytes);
  39. }
  40. public IntPtr Address { get; }
  41. public Vector Dpi { get; } = new Vector(96, 96);
  42. public PixelFormat Format { get; }
  43. public int Height { get; }
  44. public int RowBytes { get; }
  45. public int Width { get; }
  46. public void Dispose()
  47. {
  48. //no-op
  49. }
  50. public ILockedFramebuffer Lock()
  51. {
  52. return this;
  53. }
  54. public void Deallocate() => Marshal.FreeHGlobal(Address);
  55. }
  56. #if AVALONIA_SKIA
  57. [Theory]
  58. #else
  59. [Theory(Skip = "Framebuffer not supported")]
  60. #endif
  61. [InlineData(PixelFormat.Rgba8888), InlineData(PixelFormat.Bgra8888), InlineData(PixelFormat.Rgb565)]
  62. public void FramebufferRenderResultsShouldBeUsableAsBitmap(PixelFormat fmt)
  63. {
  64. var testName = nameof(FramebufferRenderResultsShouldBeUsableAsBitmap) + "_" + fmt;
  65. var fb = new Framebuffer(fmt, 80, 80);
  66. var r = Avalonia.AvaloniaLocator.Current.GetService<IPlatformRenderInterface>();
  67. using (var target = r.CreateRenderTarget(new object[] { fb }))
  68. using (var ctx = target.CreateDrawingContext(null))
  69. {
  70. ctx.Clear(Colors.Transparent);
  71. ctx.PushOpacity(0.8);
  72. ctx.FillRectangle(Brushes.Chartreuse, new Rect(0, 0, 20, 100));
  73. ctx.FillRectangle(Brushes.Crimson, new Rect(20, 0, 20, 100));
  74. ctx.FillRectangle(Brushes.Gold, new Rect(40, 0, 20, 100));
  75. }
  76. var bmp = new Bitmap(fmt, fb.Address, fb.Width, fb.Height, fb.RowBytes);
  77. fb.Deallocate();
  78. using (var rtb = new RenderTargetBitmap(100, 100))
  79. {
  80. using (var ctx = rtb.CreateDrawingContext(null))
  81. {
  82. ctx.FillRectangle(Brushes.Blue, new Rect(0, 0, 100, 100));
  83. ctx.FillRectangle(Brushes.Pink, new Rect(0, 20, 100, 10));
  84. var rc = new Rect(0, 0, 60, 60);
  85. ctx.DrawImage(bmp.PlatformImpl, 1, rc, rc);
  86. }
  87. rtb.Save(System.IO.Path.Combine(OutputPath, testName + ".out.png"));
  88. }
  89. CompareImages(testName);
  90. }
  91. #if AVALONIA_CAIRO
  92. //wontfix
  93. #else
  94. [Theory]
  95. #endif
  96. [InlineData(PixelFormat.Bgra8888), InlineData(PixelFormat.Rgba8888)]
  97. public void WritableBitmapShouldBeUsable(PixelFormat fmt)
  98. {
  99. var writableBitmap = new WritableBitmap(256, 256, fmt);
  100. var data = new int[256 * 256];
  101. for (int y = 0; y < 256; y++)
  102. for (int x = 0; x < 256; x++)
  103. data[y * 256 + x] =(int)((uint)(x + (y << 8)) | 0xFF000000u);
  104. using (var l = writableBitmap.Lock())
  105. {
  106. for(var r = 0; r<256; r++)
  107. {
  108. Marshal.Copy(data, r * 256, new IntPtr(l.Address.ToInt64() + r * l.RowBytes), 256);
  109. }
  110. }
  111. var name = nameof(WritableBitmapShouldBeUsable) + "_" + fmt;
  112. writableBitmap.Save(System.IO.Path.Combine(OutputPath, name + ".out.png"));
  113. CompareImages(name);
  114. }
  115. }
  116. }