SingleLayerRenderer.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using PixiEditor.Helpers.Extensions;
  2. using PixiEditor.Models.Layers;
  3. using SkiaSharp;
  4. using System;
  5. using System.ComponentModel;
  6. using System.Windows;
  7. using System.Windows.Media;
  8. using System.Windows.Media.Imaging;
  9. namespace PixiEditor.Models.Controllers
  10. {
  11. public class SingleLayerRenderer : INotifyPropertyChanged, IDisposable
  12. {
  13. private SKPaint BlendingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.SrcOver };
  14. private Layer layer;
  15. private SKSurface backingSurface;
  16. private WriteableBitmap finalBitmap;
  17. public WriteableBitmap FinalBitmap
  18. {
  19. get => finalBitmap;
  20. set
  21. {
  22. finalBitmap = value;
  23. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FinalBitmap)));
  24. }
  25. }
  26. public event PropertyChangedEventHandler PropertyChanged;
  27. public SingleLayerRenderer(Layer layer, int width, int height)
  28. {
  29. this.layer = layer;
  30. layer.LayerBitmapChanged += OnLayerBitmapChanged;
  31. Resize(width, height);
  32. }
  33. public void Resize(int newWidth, int newHeight)
  34. {
  35. backingSurface?.Dispose();
  36. finalBitmap = new WriteableBitmap(newWidth, newHeight, 96, 96, PixelFormats.Pbgra32, null);
  37. var imageInfo = new SKImageInfo(newWidth, newHeight, SKColorType.Bgra8888, SKAlphaType.Premul, SKColorSpace.CreateSrgb());
  38. backingSurface = SKSurface.Create(imageInfo, finalBitmap.BackBuffer, finalBitmap.BackBufferStride);
  39. Update(new Int32Rect(0, 0, newWidth, newHeight));
  40. }
  41. public void Dispose()
  42. {
  43. backingSurface.Dispose();
  44. BlendingPaint.Dispose();
  45. layer.LayerBitmapChanged -= OnLayerBitmapChanged;
  46. }
  47. private void Update(Int32Rect dirtyRectangle)
  48. {
  49. backingSurface.Canvas.Clear();
  50. finalBitmap.Lock();
  51. if (layer.IsVisible)
  52. {
  53. BlendingPaint.Color = new SKColor(255, 255, 255, (byte)(layer.Opacity * 255));
  54. layer.LayerBitmap.SkiaSurface.Draw(
  55. backingSurface.Canvas,
  56. layer.OffsetX,
  57. layer.OffsetY,
  58. BlendingPaint);
  59. }
  60. dirtyRectangle = dirtyRectangle.Intersect(new Int32Rect(0, 0, finalBitmap.PixelWidth, finalBitmap.PixelHeight));
  61. finalBitmap.AddDirtyRect(dirtyRectangle);
  62. finalBitmap.Unlock();
  63. }
  64. private void OnLayerBitmapChanged(object sender, Int32Rect e)
  65. {
  66. Update(e);
  67. }
  68. }
  69. }