Compare commits

..

1 Commits

Author SHA1 Message Date
swcs 82bc1e72c6 stop throwing exceptions for color validation 2023-05-18 17:50:21 +02:00
14 changed files with 34 additions and 144 deletions
+5 -34
View File
@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Linq;
using NUnit.Framework;
using QuestPDF.Drawing.Exceptions;
using QuestPDF.Examples.Engine;
@@ -80,11 +79,11 @@ namespace QuestPDF.Examples
.ShowResults()
.Render(page =>
{
page.Padding(15).Column(column =>
page.Padding(10).Column(column =>
{
column.Spacing(15);
column.Spacing(10);
column.Item().Image("photo.jpg").WithRasterDpi(16).FitUnproportionally();
column.Item().Image("photo.jpg").WithRasterDpi(16);
column.Item().Image("photo.jpg").WithRasterDpi(72);
});
});
@@ -100,9 +99,9 @@ namespace QuestPDF.Examples
.ShowResults()
.Render(page =>
{
page.Padding(15).Column(column =>
page.Padding(10).Column(column =>
{
column.Spacing(15);
column.Spacing(10);
column.Item().Image("photo.jpg").WithCompressionQuality(ImageCompressionQuality.VeryLow).WithRasterDpi(72);
column.Item().Image("photo.jpg").WithCompressionQuality(ImageCompressionQuality.High).WithRasterDpi(72);
@@ -110,34 +109,6 @@ 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,9 +38,6 @@
<None Update="photo.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="checkbox.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Binary file not shown.

Before

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);
var sharedImage = DocumentImage.FromBinaryData(photo).DisposeAfterDocumentGeneration();
foreach (var i in Enumerable.Range(0, 10))
column.Item().Image(sharedImage);
+5 -8
View File
@@ -52,7 +52,7 @@ namespace QuestPDF.Drawing
var documentSettings = document.GetSettings();
documentSettings.ImageRasterDpi = settings.RasterDpi;
var canvas = new ImageCanvas(settings);
RenderDocument(canvas, document, documentSettings, useOriginalImages: true);
RenderDocument(canvas, document, documentSettings);
return canvas.Images;
}
@@ -93,7 +93,7 @@ namespace QuestPDF.Drawing
return canvas.Pictures;
}
internal static void RenderDocument<TCanvas>(TCanvas canvas, IDocument document, DocumentSettings settings, bool useOriginalImages = false)
internal static void RenderDocument<TCanvas>(TCanvas canvas, IDocument document, DocumentSettings settings)
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, useOriginalImages);
ApplyDefaultImageConfiguration(content, settings.ImageRasterDpi, settings.ImageCompressionQuality);
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, bool useOriginalImages)
internal static void ApplyDefaultImageConfiguration(this Element? content, int imageRasterDpi, ImageCompressionQuality imageCompressionQuality)
{
content.VisitChildren(x =>
{
@@ -237,28 +237,25 @@ 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>())
{
textBlockElement.Element.ApplyDefaultImageConfiguration(imageRasterDpi, imageCompressionQuality, useOriginalImages);
textBlockElement.Element.ApplyDefaultImageConfiguration(imageRasterDpi, imageCompressionQuality);
}
}
});
+1 -1
View File
@@ -42,7 +42,7 @@ namespace QuestPDF.Drawing
public override void EndPage()
{
Canvas.Save();
var image = Surface.Snapshot().Encode(Settings.ImageFormat.ToSkImageFormat(), Settings.ImageCompressionQuality.ToQualityValue()).ToArray();
var image = Surface.Snapshot().Encode(Settings.Format, Settings.Quality).ToArray();
Images.Add(image);
Canvas.Dispose();
+1 -4
View File
@@ -16,7 +16,6 @@ namespace QuestPDF.Elements
internal int? ImageTargetDpi { get; set; }
internal ImageCompressionQuality? ImageCompressionQuality { get; set; }
internal bool UseOriginalImage { get; set; }
public DynamicHost(DynamicComponentProxy child)
{
@@ -64,7 +63,6 @@ namespace QuestPDF.Elements
ImageTargetDpi = ImageTargetDpi.Value,
ImageCompressionQuality = ImageCompressionQuality.Value,
UseOriginalImage = UseOriginalImage,
PageNumber = PageContext.CurrentPage,
TotalPages = PageContext.GetLocation(Infrastructure.PageContext.DocumentLocation).PageEnd,
@@ -90,7 +88,6 @@ 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; }
@@ -103,7 +100,7 @@ namespace QuestPDF.Elements
container.ApplyInheritedAndGlobalTexStyle(TextStyle);
container.ApplyContentDirection(ContentDirection);
container.ApplyDefaultImageConfiguration(ImageTargetDpi, ImageCompressionQuality, UseOriginalImage);
container.ApplyDefaultImageConfiguration(ImageTargetDpi, ImageCompressionQuality);
container.InjectDependencies(PageContext, Canvas);
container.VisitChildren(x => (x as IStateResettable)?.ResetState());
-8
View File
@@ -13,7 +13,6 @@ 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)
@@ -32,13 +31,6 @@ 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);
+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);
var image = Infrastructure.Image.FromBinaryData(imageData).DisposeAfterDocumentGeneration();
return parent.Image(image);
}
public static ImageDescriptor Image(this IContainer parent, string filePath)
{
var image = Infrastructure.Image.FromFile(filePath);
var image = Infrastructure.Image.FromFile(filePath).DisposeAfterDocumentGeneration();
return parent.Image(image);
}
public static ImageDescriptor Image(this IContainer parent, Stream fileStream)
{
var image = Infrastructure.Image.FromStream(fileStream);
var image = Infrastructure.Image.FromStream(fileStream).DisposeAfterDocumentGeneration();
return parent.Image(image);
}
+1 -9
View File
@@ -26,15 +26,7 @@ namespace QuestPDF.Helpers
static bool IsColorValid(string color)
{
try
{
SKColor.Parse(color);
return true;
}
catch
{
return false;
}
return SKColor.TryParse(color, out _);
}
}
}
-11
View File
@@ -62,17 +62,6 @@ namespace QuestPDF.Helpers
return size.Width < 0f || size.Height < 0f;
}
internal static SKEncodedImageFormat ToSkImageFormat(this ImageFormat format)
{
return format switch
{
ImageFormat.Jpeg => SKEncodedImageFormat.Jpeg,
ImageFormat.Png => SKEncodedImageFormat.Png,
ImageFormat.Webp=> SKEncodedImageFormat.Webp,
_ => throw new ArgumentOutOfRangeException(nameof(format), format, null)
};
}
internal static int ToQualityValue(this ImageCompressionQuality quality)
{
return quality switch
+10 -47
View File
@@ -13,29 +13,28 @@ namespace QuestPDF.Infrastructure
internal ImageCompressionQuality CompressionQuality { get; set; }
}
public class Image
public class Image : IDisposable
{
internal SKImage SkImage { get; }
internal ImageSize Size { get; }
internal bool IsDocumentScoped { get; }
internal bool IsDocumentScoped { get; set; }
internal LinkedList<(GetImageVersionRequest request, SKImage image)> ScaledImageCache { get; } = new();
internal Image(SKImage image, bool isDocumentScoped)
private Image(SKImage image)
{
SkImage = image;
IsDocumentScoped = isDocumentScoped;
Size = new ImageSize(image.Width, image.Height);
}
internal void Dispose()
public void Dispose()
{
SkImage.Dispose();
foreach (var cacheKey in ScaledImageCache)
cacheKey.image.Dispose();
}
#region Scaling Image
internal SKImage GetVersionOfSize(GetImageVersionRequest request)
@@ -80,51 +79,15 @@ namespace QuestPDF.Infrastructure
if (image == null)
throw new DocumentComposeException("Cannot load or decode provided image.");
return new Image(image, true);
return new Image(image);
}
#endregion
}
public class SharedImage : Image, IDisposable
{
internal SharedImage(SKImage image) : base(image, false)
internal Image DisposeAfterDocumentGeneration()
{
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
}
}
@@ -1,9 +0,0 @@
namespace QuestPDF.Infrastructure
{
public enum ImageFormat
{
Jpeg,
Png,
Webp
}
}
@@ -7,19 +7,20 @@ namespace QuestPDF.Infrastructure
/// <summary>
/// The file format used to encode the image(s).
/// </summary>
public ImageFormat ImageFormat { get; set; } = ImageFormat.Png;
public SKEncodedImageFormat Format { get; set; } = SKEncodedImageFormat.Png;
/// <summary>
/// Encoding quality controls the trade-off between size and quality.
/// The default value is "high quality".
/// The quality level to use for the image(s). This is in the range from 0-100.
/// </summary>
public ImageCompressionQuality ImageCompressionQuality { get; set; } = ImageCompressionQuality.VeryHigh;
public int Quality { get; set; } = 100;
/// <summary>
/// The DPI (pixels-per-inch) at which the document will be rasterized. This parameter controls the resolution of produced images.
/// The DPI (pixels-per-inch) at which images and features without native PDF support will be rasterized.
/// A larger DPI would create a PDF that reflects the original intent with better fidelity, but it can make for larger PDF files too, which would use more memory while rendering, and it would be slower to be processed or sent online or to printer.
/// When generating images, this parameter also controls the resolution of the generated content.
/// Default value is 144.
/// </summary>
public int RasterDpi { get; set; } = DocumentSettings.DefaultRasterDpi * 2;
public int RasterDpi { get; set; } = 144;
public static ImageGenerationSettings Default => new ImageGenerationSettings();