diff --git a/Source/QuestPDF.Examples/ImageExamples.cs b/Source/QuestPDF.Examples/ImageExamples.cs
index bd81b65..48d4db1 100644
--- a/Source/QuestPDF.Examples/ImageExamples.cs
+++ b/Source/QuestPDF.Examples/ImageExamples.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Linq;
using NUnit.Framework;
using QuestPDF.Drawing.Exceptions;
using QuestPDF.Examples.Engine;
@@ -79,11 +80,11 @@ namespace QuestPDF.Examples
.ShowResults()
.Render(page =>
{
- page.Padding(10).Column(column =>
+ page.Padding(15).Column(column =>
{
- column.Spacing(10);
+ column.Spacing(15);
- column.Item().Image("photo.jpg").WithRasterDpi(16);
+ column.Item().Image("photo.jpg").WithRasterDpi(16).FitUnproportionally();
column.Item().Image("photo.jpg").WithRasterDpi(72);
});
});
@@ -99,9 +100,9 @@ namespace QuestPDF.Examples
.ShowResults()
.Render(page =>
{
- page.Padding(10).Column(column =>
+ page.Padding(15).Column(column =>
{
- column.Spacing(10);
+ column.Spacing(15);
column.Item().Image("photo.jpg").WithCompressionQuality(ImageCompressionQuality.VeryLow).WithRasterDpi(72);
column.Item().Image("photo.jpg").WithCompressionQuality(ImageCompressionQuality.High).WithRasterDpi(72);
@@ -109,6 +110,34 @@ namespace QuestPDF.Examples
});
}
+ [Test]
+ public void ReusingImage_With()
+ {
+ RenderingTest
+ .Create()
+ .PageSize(400, 600)
+ .ProduceImages()
+ .ShowResults()
+ .Render(page =>
+ {
+ page.Padding(15).Column(column =>
+ {
+ column.Spacing(15);
+
+ var image = Image.FromFile("checkbox.png");
+
+ foreach (var i in Enumerable.Range(0, 5))
+ {
+ column.Item().Row(row =>
+ {
+ row.AutoItem().Width(24).Image(image);
+ row.RelativeItem().PaddingLeft(8).AlignMiddle().Text(Placeholders.Label()).FontSize(16);
+ });
+ }
+ });
+ });
+ }
+
[Test]
public void Exception()
{
diff --git a/Source/QuestPDF.Examples/QuestPDF.Examples.csproj b/Source/QuestPDF.Examples/QuestPDF.Examples.csproj
index 5f07fa7..4547520 100644
--- a/Source/QuestPDF.Examples/QuestPDF.Examples.csproj
+++ b/Source/QuestPDF.Examples/QuestPDF.Examples.csproj
@@ -38,6 +38,9 @@
PreserveNewest
+
+ PreserveNewest
+
diff --git a/Source/QuestPDF.Examples/checkbox.png b/Source/QuestPDF.Examples/checkbox.png
new file mode 100644
index 0000000..57422a7
Binary files /dev/null and b/Source/QuestPDF.Examples/checkbox.png differ
diff --git a/Source/QuestPDF.UnitTests/ImageTests.cs b/Source/QuestPDF.UnitTests/ImageTests.cs
index 3c70a33..5db35d9 100644
--- a/Source/QuestPDF.UnitTests/ImageTests.cs
+++ b/Source/QuestPDF.UnitTests/ImageTests.cs
@@ -85,7 +85,7 @@ namespace QuestPDF.UnitTests
{
container.Column(column =>
{
- var sharedImage = DocumentImage.FromBinaryData(photo).DisposeAfterDocumentGeneration();
+ var sharedImage = DocumentImage.FromBinaryData(photo);
foreach (var i in Enumerable.Range(0, 10))
column.Item().Image(sharedImage);
diff --git a/Source/QuestPDF/Drawing/DocumentGenerator.cs b/Source/QuestPDF/Drawing/DocumentGenerator.cs
index fd64509..d1c07ee 100644
--- a/Source/QuestPDF/Drawing/DocumentGenerator.cs
+++ b/Source/QuestPDF/Drawing/DocumentGenerator.cs
@@ -52,7 +52,7 @@ namespace QuestPDF.Drawing
var documentSettings = document.GetSettings();
documentSettings.ImageRasterDpi = settings.RasterDpi;
var canvas = new ImageCanvas(settings);
- RenderDocument(canvas, document, documentSettings);
+ RenderDocument(canvas, document, documentSettings, useOriginalImages: true);
return canvas.Images;
}
@@ -93,7 +93,7 @@ namespace QuestPDF.Drawing
return canvas.Pictures;
}
- internal static void RenderDocument(TCanvas canvas, IDocument document, DocumentSettings settings)
+ internal static void RenderDocument(TCanvas canvas, IDocument document, DocumentSettings settings, bool useOriginalImages = false)
where TCanvas : ICanvas, IRenderingCanvas
{
var container = new DocumentContainer();
@@ -102,7 +102,7 @@ namespace QuestPDF.Drawing
ApplyInheritedAndGlobalTexStyle(content, TextStyle.Default);
ApplyContentDirection(content, settings.ContentDirection);
- ApplyDefaultImageConfiguration(content, settings.ImageRasterDpi, settings.ImageCompressionQuality);
+ ApplyDefaultImageConfiguration(content, settings.ImageRasterDpi, settings.ImageCompressionQuality, useOriginalImages);
var debuggingState = Settings.EnableDebugging ? ApplyDebugging(content) : null;
@@ -229,7 +229,7 @@ namespace QuestPDF.Drawing
ApplyContentDirection(child, direction);
}
- internal static void ApplyDefaultImageConfiguration(this Element? content, int imageRasterDpi, ImageCompressionQuality imageCompressionQuality)
+ internal static void ApplyDefaultImageConfiguration(this Element? content, int imageRasterDpi, ImageCompressionQuality imageCompressionQuality, bool useOriginalImages)
{
content.VisitChildren(x =>
{
@@ -237,25 +237,28 @@ namespace QuestPDF.Drawing
{
image.TargetDpi ??= imageRasterDpi;
image.CompressionQuality ??= imageCompressionQuality;
+ image.UseOriginalImage |= useOriginalImages;
}
if (x is QuestPDF.Elements.DynamicImage dynamicImage)
{
dynamicImage.TargetDpi ??= imageRasterDpi;
dynamicImage.CompressionQuality ??= imageCompressionQuality;
+ dynamicImage.UseOriginalImage |= useOriginalImages;
}
if (x is DynamicHost dynamicHost)
{
dynamicHost.ImageTargetDpi ??= imageRasterDpi;
dynamicHost.ImageCompressionQuality ??= imageCompressionQuality;
+ dynamicHost.UseOriginalImage |= useOriginalImages;
}
if (x is TextBlock textBlock)
{
foreach (var textBlockElement in textBlock.Items.OfType())
{
- textBlockElement.Element.ApplyDefaultImageConfiguration(imageRasterDpi, imageCompressionQuality);
+ textBlockElement.Element.ApplyDefaultImageConfiguration(imageRasterDpi, imageCompressionQuality, useOriginalImages);
}
}
});
diff --git a/Source/QuestPDF/Elements/Dynamic.cs b/Source/QuestPDF/Elements/Dynamic.cs
index 3d1dbcc..f15a404 100644
--- a/Source/QuestPDF/Elements/Dynamic.cs
+++ b/Source/QuestPDF/Elements/Dynamic.cs
@@ -16,6 +16,7 @@ namespace QuestPDF.Elements
internal int? ImageTargetDpi { get; set; }
internal ImageCompressionQuality? ImageCompressionQuality { get; set; }
+ internal bool UseOriginalImage { get; set; }
public DynamicHost(DynamicComponentProxy child)
{
@@ -63,6 +64,7 @@ namespace QuestPDF.Elements
ImageTargetDpi = ImageTargetDpi.Value,
ImageCompressionQuality = ImageCompressionQuality.Value,
+ UseOriginalImage = UseOriginalImage,
PageNumber = PageContext.CurrentPage,
TotalPages = PageContext.GetLocation(Infrastructure.PageContext.DocumentLocation).PageEnd,
@@ -88,6 +90,7 @@ namespace QuestPDF.Elements
internal int ImageTargetDpi { get; set; }
internal ImageCompressionQuality ImageCompressionQuality { get; set; }
+ internal bool UseOriginalImage { get; set; }
public int PageNumber { get; internal set; }
public int TotalPages { get; internal set; }
@@ -100,7 +103,7 @@ namespace QuestPDF.Elements
container.ApplyInheritedAndGlobalTexStyle(TextStyle);
container.ApplyContentDirection(ContentDirection);
- container.ApplyDefaultImageConfiguration(ImageTargetDpi, ImageCompressionQuality);
+ container.ApplyDefaultImageConfiguration(ImageTargetDpi, ImageCompressionQuality, UseOriginalImage);
container.InjectDependencies(PageContext, Canvas);
container.VisitChildren(x => (x as IStateResettable)?.ResetState());
diff --git a/Source/QuestPDF/Elements/DynamicImage.cs b/Source/QuestPDF/Elements/DynamicImage.cs
index 4441c63..d5d7028 100644
--- a/Source/QuestPDF/Elements/DynamicImage.cs
+++ b/Source/QuestPDF/Elements/DynamicImage.cs
@@ -13,6 +13,7 @@ namespace QuestPDF.Elements
{
internal int? TargetDpi { get; set; }
internal ImageCompressionQuality? CompressionQuality { get; set; }
+ internal bool UseOriginalImage { get; set; }
public GenerateDynamicImageDelegate? Source { get; set; }
internal override SpacePlan Measure(Size availableSpace)
@@ -31,6 +32,13 @@ namespace QuestPDF.Elements
return;
using var originalImage = SKImage.FromEncodedData(imageData);
+
+ if (UseOriginalImage)
+ {
+ Canvas.DrawImage(originalImage, Position.Zero, availableSpace);
+ return;
+ }
+
using var compressedImage = originalImage.CompressImage(CompressionQuality.Value);
var targetImage = Helpers.Helpers.GetImageWithSmallerSize(originalImage, compressedImage);
diff --git a/Source/QuestPDF/Fluent/ImageExtensions.cs b/Source/QuestPDF/Fluent/ImageExtensions.cs
index 2b64836..c8b4fa7 100644
--- a/Source/QuestPDF/Fluent/ImageExtensions.cs
+++ b/Source/QuestPDF/Fluent/ImageExtensions.cs
@@ -109,19 +109,19 @@ namespace QuestPDF.Fluent
{
public static ImageDescriptor Image(this IContainer parent, byte[] imageData)
{
- var image = Infrastructure.Image.FromBinaryData(imageData).DisposeAfterDocumentGeneration();
+ var image = Infrastructure.Image.FromBinaryData(imageData);
return parent.Image(image);
}
public static ImageDescriptor Image(this IContainer parent, string filePath)
{
- var image = Infrastructure.Image.FromFile(filePath).DisposeAfterDocumentGeneration();
+ var image = Infrastructure.Image.FromFile(filePath);
return parent.Image(image);
}
public static ImageDescriptor Image(this IContainer parent, Stream fileStream)
{
- var image = Infrastructure.Image.FromStream(fileStream).DisposeAfterDocumentGeneration();
+ var image = Infrastructure.Image.FromStream(fileStream);
return parent.Image(image);
}
diff --git a/Source/QuestPDF/Infrastructure/Image.cs b/Source/QuestPDF/Infrastructure/Image.cs
index 5ed6579..eb1bc73 100644
--- a/Source/QuestPDF/Infrastructure/Image.cs
+++ b/Source/QuestPDF/Infrastructure/Image.cs
@@ -13,28 +13,29 @@ namespace QuestPDF.Infrastructure
internal ImageCompressionQuality CompressionQuality { get; set; }
}
- public class Image : IDisposable
+ public class Image
{
internal SKImage SkImage { get; }
internal ImageSize Size { get; }
- internal bool IsDocumentScoped { get; set; }
+ internal bool IsDocumentScoped { get; }
internal LinkedList<(GetImageVersionRequest request, SKImage image)> ScaledImageCache { get; } = new();
- private Image(SKImage image)
+ internal Image(SKImage image, bool isDocumentScoped)
{
SkImage = image;
+ IsDocumentScoped = isDocumentScoped;
Size = new ImageSize(image.Width, image.Height);
}
-
- public void Dispose()
+
+ internal void Dispose()
{
SkImage.Dispose();
foreach (var cacheKey in ScaledImageCache)
cacheKey.image.Dispose();
}
-
+
#region Scaling Image
internal SKImage GetVersionOfSize(GetImageVersionRequest request)
@@ -79,15 +80,51 @@ namespace QuestPDF.Infrastructure
if (image == null)
throw new DocumentComposeException("Cannot load or decode provided image.");
- return new Image(image);
+ return new Image(image, true);
}
#endregion
+ }
- internal Image DisposeAfterDocumentGeneration()
+ public class SharedImage : Image, IDisposable
+ {
+ internal SharedImage(SKImage image) : base(image, false)
{
- IsDocumentScoped = true;
- return this;
+
}
+
+ public void Dispose()
+ {
+ base.Dispose();
+ }
+
+ #region public constructors
+
+ public static new SharedImage FromBinaryData(byte[] imageData)
+ {
+ return CreateImage(SKImage.FromEncodedData(imageData));
+ }
+
+ public static new SharedImage FromFile(string filePath)
+ {
+ return CreateImage(SKImage.FromEncodedData(filePath));
+ }
+
+ public static new SharedImage FromStream(Stream fileStream)
+ {
+ return CreateImage(SKImage.FromEncodedData(fileStream));
+ }
+
+ private static SharedImage CreateImage(SKImage? image)
+ {
+ if (image == null)
+ throw new DocumentComposeException("Cannot load or decode provided image.");
+
+ var result = new SharedImage(image);
+
+ return result;
+ }
+
+ #endregion
}
}
\ No newline at end of file