using System.Diagnostics; using System.Runtime.InteropServices; using Avalonia; using Avalonia.Controls; using Avalonia.LogicalTree; using Avalonia.Media; using Avalonia.Media.Imaging; using Avalonia.Media.Immutable; using Avalonia.Platform; using Avalonia.Threading; namespace RenderDemo.Pages { public class WriteableBitmapPage : Control { private WriteableBitmap _unpremulBitmap; private WriteableBitmap _premulBitmap; private readonly Stopwatch _st = Stopwatch.StartNew(); protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) { _unpremulBitmap = new WriteableBitmap(new PixelSize(256, 256), new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Unpremul); _premulBitmap = new WriteableBitmap(new PixelSize(256, 256), new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul); base.OnAttachedToLogicalTree(e); } protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e) { base.OnDetachedFromLogicalTree(e); _unpremulBitmap?.Dispose(); _unpremulBitmap = null; _premulBitmap?.Dispose(); _unpremulBitmap = null; } public override void Render(DrawingContext context) { void FillPixels(WriteableBitmap bitmap, byte fillAlpha, bool premul) { using (var fb = bitmap.Lock()) { var data = new int[fb.Size.Width * fb.Size.Height]; for (int y = 0; y < fb.Size.Height; y++) { for (int x = 0; x < fb.Size.Width; x++) { var color = new Color(fillAlpha, 0, 255, 0); if (premul) { byte r = (byte) (color.R * color.A / 255); byte g = (byte) (color.G * color.A / 255); byte b = (byte) (color.B * color.A / 255); color = new Color(fillAlpha, r, g, b); } data[y * fb.Size.Width + x] = (int) color.ToUInt32(); } } Marshal.Copy(data, 0, fb.Address, fb.Size.Width * fb.Size.Height); } } base.Render(context); byte alpha = (byte)((_st.ElapsedMilliseconds / 10) % 256); FillPixels(_unpremulBitmap, alpha, false); FillPixels(_premulBitmap, alpha, true); context.FillRectangle(Brushes.Red, new Rect(0, 0, 256 * 3, 256)); context.DrawImage(_unpremulBitmap, new Rect(0, 0, 256, 256), new Rect(0, 0, 256, 256)); context.DrawImage(_premulBitmap, new Rect(0, 0, 256, 256), new Rect(256, 0, 256, 256)); context.FillRectangle(new ImmutableSolidColorBrush(Colors.Lime, alpha / 255d), new Rect(512, 0, 256, 256)); Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background); } } }