Improved SharedImage API

This commit is contained in:
MarcinZiabek
2023-05-20 01:16:24 +02:00
parent 312e94a4bd
commit b74e0327fa
6 changed files with 88 additions and 19 deletions
+34 -5
View File
@@ -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()
{
@@ -38,6 +38,9 @@
<None Update="photo.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="checkbox.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

+1 -1
View File
@@ -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);
+3 -3
View File
@@ -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);
}
+47 -10
View File
@@ -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
}
}