.net SkiaSharp将SVG转换为PNG -图像不完全适合画布大小

vmdwslir  于 2023-10-21  发布在  .NET
关注(0)|答案(1)|浏览(234)

我尝试使用SkiaSharp将SVG图像转换为PNG,并返回一个带有图像的PdfSharp XImage对象,以便将其添加到PDF页面(因为PdfSharp不直接支持SVG格式)。
这是我的代码:

  1. private XImage LoadSvgIcon(string iconUrl)
  2. {
  3. XElement root = XElement.Load(iconUrl);
  4. using (Stream xmlStream = new MemoryStream())
  5. {
  6. root.Save(xmlStream);
  7. xmlStream.Flush();
  8. xmlStream.Position = 0;
  9. var svg = new SkiaSharp.Extended.Svg.SKSvg();
  10. svg.Load(xmlStream);
  11. var bitmap = new SKBitmap((int)svg.CanvasSize.Width, (int)svg.CanvasSize.Height);
  12. var canvas = new SKCanvas(bitmap);
  13. var p = new SKPaint();
  14. p.Color = SKColor.Parse("#219de1");
  15. canvas.DrawPaint(p);
  16. canvas.DrawPicture(svg.Picture);
  17. using (var skData = SKImage.FromBitmap(bitmap).Encode(SKEncodedImageFormat.Png, 100))
  18. {
  19. Stream stream = new MemoryStream();
  20. skData.SaveTo(stream);
  21. return XImage.FromStream(stream);
  22. }
  23. }
  24. }

即使我将画布的大小设置为SVG的大小,SVG也不会占用画布的整个空间(可以看到画布的背景是蓝色的,而SVG本身的背景是红色的,里面有图标-您可以看到它并没有占用整个画布空间)。
我错过了什么?

cuxqih21

cuxqih211#

可以尝试从弃用的Extended.Svg切换到Svg.Skia nuget。你想缩放svg来填充所需的画布大小,这个过程实际上和缩放加载的位图来填充画布是一样的,有很多例子。只是一些代码,来说明这个想法:

  1. if (Svg != null) // this is your loaded svg
  2. {
  3. SKMatrix matrix = CreateSvgMatrix(area, scale); //SKRect area you wont to use/fill
  4. using (var paint = new SKPaint())
  5. {
  6. paint.IsAntialias = true;
  7. //could also tint the svg:
  8. paint.ColorFilter = SKColorFilter.CreateBlendMode(TintColor.ToSKColor(), SKBlendMode.SrcIn);
  9. ctx.Canvas.DrawPicture(Svg.Picture, ref matrix, paint);
  10. }
  11. }
  12. SKMatrix CreateSvgMatrix(SKRect destination, double scale)
  13. {
  14. #region Layout
  15. SKRect contentSize = Svg.Picture.CullRect;
  16. float scaledContentWidth = (float)(contentSize.Width);
  17. float scaledContentHeight = (float)(contentSize.Height);
  18. //multipliers to reduce
  19. float xRatio = destination.Width / scaledContentWidth;
  20. float yRatio = destination.Height / scaledContentHeight;
  21. var aspectX = xRatio;
  22. var aspectY = yRatio;
  23. var adjustX = 0f;
  24. var adjustY = 0f;
  25. if (Aspect == TransformAspect.Fill)
  26. {
  27. //multipliers to enlarge
  28. if (destination.Width > scaledContentWidth && aspectX < 1)
  29. {
  30. aspectX = 1 + (1 - aspectX);
  31. }
  32. if (destination.Height > scaledContentHeight && aspectY < 1)
  33. {
  34. aspectY = 1 + (1 - aspectY);
  35. }
  36. adjustX = (destination.Width - scaledContentWidth * aspectX) / 2.0f;
  37. adjustY = (destination.Height - scaledContentHeight * aspectY) / 2.0f;
  38. }
  39. else
  40. if (Aspect == TransformAspect.AspectFill)
  41. {
  42. var needMoreY = destination.Height - scaledContentHeight * xRatio;
  43. var needMoreX = destination.Width - scaledContentWidth * yRatio;
  44. var needMore = Math.Max(needMoreX, needMoreY);
  45. if (needMore > 0)
  46. {
  47. var moreX = needMore / scaledContentWidth;
  48. var moreY = needMore / scaledContentHeight;
  49. xRatio += moreX;
  50. yRatio += moreY;
  51. }
  52. if (destination.Width < destination.Height)
  53. {
  54. aspectX = xRatio;
  55. aspectY = xRatio;
  56. }
  57. else
  58. {
  59. aspectX = yRatio;
  60. aspectY = yRatio;
  61. }
  62. adjustX = (destination.Width - scaledContentWidth * aspectX) / 2.0f;
  63. adjustY = (destination.Height - scaledContentHeight * aspectY) / 2.0f;
  64. }
  65. else //FIT
  66. {
  67. //keep aspect
  68. var aspectFit = Math.Min(xRatio / ZoomX, yRatio / ZoomY);
  69. var aspectFitX = (float)(aspectFit * ZoomX * Zoom);
  70. var aspectFitY = (float)(aspectFit * ZoomY * Zoom);
  71. if (yRatio == aspectFit) // was fit for by height, need to center x
  72. {
  73. adjustX = (destination.Width - scaledContentWidth * aspectFitX) / 2.0f;
  74. }
  75. else// was fit for by width, need to center y
  76. {
  77. adjustY = (destination.Height - scaledContentHeight * aspectFitY) / 2.0f;
  78. }
  79. aspectX = aspectFitX;
  80. aspectY = aspectFitY;
  81. }
  82. var matrix = new SKMatrix
  83. {
  84. ScaleX = aspectX,
  85. SkewX = 0,
  86. TransX = destination.Left + adjustX + (float)Math.Round(HorizontalOffset * scale),
  87. SkewY = 0,
  88. ScaleY = aspectY,
  89. TransY = destination.Top + adjustY + (float)Math.Round(VerticalOffset * scale),
  90. Persp0 = 0,
  91. Persp1 = 0,
  92. Persp2 = 1
  93. };
  94. return matrix;
  95. #endregion
  96. }
展开查看全部

相关问题