Browse Source

Added a ctor for populating WriteableBitmap with initial data

pull/10120/head
Nikita Tsukanov 4 years ago
parent
commit
a0adee3d00
  1. 26
      src/Avalonia.Base/Media/Imaging/WriteableBitmap.cs
  2. 30
      tests/Avalonia.RenderTests/Media/BitmapTests.cs

26
src/Avalonia.Base/Media/Imaging/WriteableBitmap.cs

@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;
using Avalonia.Platform;
namespace Avalonia.Media.Imaging
@ -36,6 +37,31 @@ namespace Avalonia.Media.Imaging
_pixelFormatMemory = pixelFormatMemory;
}
/// <summary>
/// Initializes a new instance of the <see cref="WriteableBitmap"/> class with existing pixel data
/// The data is copied to the bitmap
/// </summary>
/// <param name="format">The pixel format.</param>
/// <param name="alphaFormat">The alpha format.</param>
/// <param name="data">The pointer to the source bytes.</param>
/// <param name="size">The size of the bitmap in device pixels.</param>
/// <param name="dpi">The DPI of the bitmap.</param>
/// <param name="stride">The number of bytes per row.</param>
public unsafe WriteableBitmap(PixelFormat format, AlphaFormat alphaFormat, IntPtr data, PixelSize size, Vector dpi, int stride)
: this(size, dpi, format, alphaFormat)
{
var minStride = (format.BitsPerPixel * size.Width + 7) / 8;
if (minStride > stride)
throw new ArgumentOutOfRangeException(nameof(stride));
using (var locked = Lock())
{
for (var y = 0; y < size.Height; y++)
Unsafe.CopyBlock((locked.Address + locked.RowBytes * y).ToPointer(),
(data + y * stride).ToPointer(), (uint)minStride);
}
}
public override PixelFormat? Format => _pixelFormatMemory?.Format ?? base.Format;
public ILockedFramebuffer Lock()

30
tests/Avalonia.RenderTests/Media/BitmapTests.cs

@ -167,10 +167,17 @@ namespace Avalonia.Direct2D1.RenderTests.Media
if (!File.Exists(Path.Combine(OutputPath, expectedName + ".expected.png")))
expectedName = Path.Combine(relativeFilesDir, "Default");
foreach (var writable in new[] { false, true })
var names = new[]
{
"_Writeable",
"_WriteableInitialized",
"_Normal"
};
foreach (var step in new[] { 0,1,2 })
{
var testName = nameof(BitmapsShouldSupportTranscoders_Lenna) + "_" + formatName +
(writable ? "_Writeable" : "_Normal");
var testName = nameof(BitmapsShouldSupportTranscoders_Lenna) + "_" + formatName + names[step];
var path = System.IO.Path.Combine(OutputPath, testName + ".out.png");
fixed (byte* pData = data)
@ -178,7 +185,7 @@ namespace Avalonia.Direct2D1.RenderTests.Media
Bitmap? b = null;
try
{
if (writable)
if (step == 0)
{
var bmp = new WriteableBitmap(size, new Vector(96, 96), new PixelFormat(format),
alphaFormat);
@ -194,15 +201,20 @@ namespace Avalonia.Direct2D1.RenderTests.Media
}
b = bmp;
var copyTo = new byte[data.Length];
fixed (byte* pCopyTo = copyTo)
b.CopyPixels(default, new IntPtr(pCopyTo), copyTo.Length, stride);
Assert.Equal(data.ToArray(), copyTo);
}
else if (step == 1)
b = new WriteableBitmap(new PixelFormat(format), alphaFormat, new IntPtr(pData),
size, new Vector(96, 96), stride);
else
{
b = new Bitmap(new PixelFormat(format), alphaFormat, new IntPtr(pData),
size, new Vector(96, 96), stride);
if (step < 2)
{
var copyTo = new byte[data.Length];
fixed (byte* pCopyTo = copyTo)
b.CopyPixels(default, new IntPtr(pCopyTo), copyTo.Length, stride);
Assert.Equal(data.ToArray(), copyTo);
}
b.Save(path);

Loading…
Cancel
Save