diff --git a/Source/QuestPDF.Examples/Engine/Helpers.cs b/Source/QuestPDF.Examples/Engine/Helpers.cs new file mode 100644 index 0000000..1659d08 --- /dev/null +++ b/Source/QuestPDF.Examples/Engine/Helpers.cs @@ -0,0 +1,22 @@ +using System; +using System.Diagnostics; +using System.IO; +using QuestPDF.Fluent; +using QuestPDF.Infrastructure; + +namespace QuestPDF.Examples.Engine +{ + public static class Helpers + { + public static void GeneratePdfAndOpen(this Document document, string? fileName = null) + { + fileName ??= $"{Guid.NewGuid():D}.pdf"; + + var filePath = Path.GetTempPath() + fileName; + var documentData = document.GeneratePdf(); + File.WriteAllBytes(filePath, documentData); + + Process.Start("explorer", filePath); + } + } +} \ No newline at end of file diff --git a/Source/QuestPDF.Examples/ImageExamples.cs b/Source/QuestPDF.Examples/ImageExamples.cs index 27c97ca..5747f26 100644 --- a/Source/QuestPDF.Examples/ImageExamples.cs +++ b/Source/QuestPDF.Examples/ImageExamples.cs @@ -89,5 +89,29 @@ namespace QuestPDF.Examples }); }); } + + [Test] + public void ImageResolutionScaling() + { + var image = Image.FromFile("large-image.jpg"); + + Document + .Create(document => + { + document.Page(page => + { + page.Size(11000, 11000); + page.Margin(50); + page.Content().Image(image); + }); + }) + .GeneratePdfAndOpen(); + + //Console.WriteLine(documentData.Length); + + // var filePath = Path.GetTempPath() + $"test.pdf"; + // File.WriteAllBytes(filePath, documentData); + // Console.WriteLine(filePath); + } } } \ No newline at end of file diff --git a/Source/QuestPDF.Examples/QuestPDF.Examples.csproj b/Source/QuestPDF.Examples/QuestPDF.Examples.csproj index a053de7..6401446 100644 --- a/Source/QuestPDF.Examples/QuestPDF.Examples.csproj +++ b/Source/QuestPDF.Examples/QuestPDF.Examples.csproj @@ -32,6 +32,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + diff --git a/Source/QuestPDF.Examples/large-image.jpg b/Source/QuestPDF.Examples/large-image.jpg new file mode 100644 index 0000000..96b8ace Binary files /dev/null and b/Source/QuestPDF.Examples/large-image.jpg differ diff --git a/Source/QuestPDF/Elements/Image.cs b/Source/QuestPDF/Elements/Image.cs index 74ba5a6..d2ea731 100644 --- a/Source/QuestPDF/Elements/Image.cs +++ b/Source/QuestPDF/Elements/Image.cs @@ -27,7 +27,7 @@ namespace QuestPDF.Elements if (DocumentImage == null) return; - Canvas.DrawImage(DocumentImage.SkImage, Position.Zero, availableSpace); + Canvas.DrawImage(DocumentImage.GetVersionOfSize(availableSpace), Position.Zero, availableSpace); } } } \ No newline at end of file diff --git a/Source/QuestPDF/Infrastructure/Image.cs b/Source/QuestPDF/Infrastructure/Image.cs index 64f5906..7fd5fe6 100644 --- a/Source/QuestPDF/Infrastructure/Image.cs +++ b/Source/QuestPDF/Infrastructure/Image.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using QuestPDF.Drawing.Exceptions; using SkiaSharp; @@ -7,7 +8,8 @@ namespace QuestPDF.Infrastructure { public class Image : IDisposable { - internal SKImage SkImage { get; } + private SKImage SkImage { get; } + internal List<(Size size, SKImage image)>? ScaledImageCache { get; } internal bool IsDocumentScoped { get; set; } public int Width => SkImage.Width; @@ -27,6 +29,34 @@ namespace QuestPDF.Infrastructure public void Dispose() { SkImage.Dispose(); + ScaledImageCache?.ForEach(x => x.image.Dispose()); + } + + internal SKImage GetVersionOfSize(Size size) + { + if (size.Width > Width || size.Height > Height) + return SkImage; + + var target = SKImage.Create(new SKImageInfo((int)size.Width, (int)size.Height)); + SkImage.ScalePixels(target.PeekPixels(), SKFilterQuality.High); + + return target; + + // bool ShouldApplyScaling() + // { + // const float tolerance = 1.1f; + // + // if (width > Width / tolerance || height > Height / tolerance) + // return false; + // + // SkImage.sca + // } + + static bool HasSimilarSize(Size a, Size b, float tolerance) + { + return (a.Width / b.Width > 1 / tolerance && a.Width / b.Width < tolerance) || + (a.Height / b.Height > 1 / tolerance && a.Height / b.Height < tolerance); + } } #region public constructors