ImageCanvas.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. using System;
  2. using System.Collections.Generic;
  3. using QuestPDF.Helpers;
  4. using QuestPDF.Infrastructure;
  5. using QuestPDF.Skia;
  6. namespace QuestPDF.Drawing
  7. {
  8. internal sealed class ImageCanvas : SkiaCanvasBase
  9. {
  10. private ImageGenerationSettings Settings { get; }
  11. private SkBitmap Bitmap { get; set; }
  12. // TODO: consider using SkSurface to cache drawing operations and then encode the surface to an image at the very end of the generation process
  13. // this change should reduce memory usage and improve performance
  14. internal ICollection<byte[]> Images { get; } = new List<byte[]>();
  15. public ImageCanvas(ImageGenerationSettings settings)
  16. {
  17. Settings = settings;
  18. }
  19. public override void BeginDocument()
  20. {
  21. }
  22. public override void EndDocument()
  23. {
  24. }
  25. public override void BeginPage(Size size)
  26. {
  27. var scalingFactor = Settings.RasterDpi / (float) PageSizes.PointsPerInch;
  28. Bitmap = new SkBitmap((int) (size.Width * scalingFactor), (int) (size.Height * scalingFactor));
  29. Canvas = SkCanvas.CreateFromBitmap(Bitmap);
  30. Canvas.Scale(scalingFactor, scalingFactor);
  31. }
  32. public override void EndPage()
  33. {
  34. Canvas.Save();
  35. using var imageData = EncodeBitmap();
  36. var imageBytes = imageData.ToSpan().ToArray();
  37. Images.Add(imageBytes);
  38. Bitmap.Dispose();
  39. SkData EncodeBitmap()
  40. {
  41. return Settings.ImageFormat switch
  42. {
  43. ImageFormat.Jpeg => Bitmap.EncodeAsJpeg(Settings.ImageCompressionQuality.ToQualityValue()),
  44. ImageFormat.Png => Bitmap.EncodeAsPng(),
  45. ImageFormat.Webp => Bitmap.EncodeAsWebp(Settings.ImageCompressionQuality.ToQualityValue()),
  46. _ => throw new ArgumentOutOfRangeException()
  47. };
  48. }
  49. }
  50. }
  51. }