From 779feceb3ab45b00b3d254d75e4ce7200a24ded1 Mon Sep 17 00:00:00 2001 From: David Sungaila Date: Tue, 25 Jun 2024 19:43:36 +0200 Subject: [PATCH] Add DpiRelativeToBounds option --- src/PDFtoImage/Conversion.cs | 94 +++++++++---------- src/PDFtoImage/IRenderOptions.cs | 7 +- src/PDFtoImage/Internals/PdfDocument.cs | 77 ++++++++++----- src/PDFtoImage/Internals/PdfFile.cs | 7 +- .../monoandroid10.0/PublicAPI.Shipped.txt | 6 +- .../PublicAPI/net462/PublicAPI.Shipped.txt | 6 +- .../PublicAPI/net471/PublicAPI.Shipped.txt | 6 +- .../PublicAPI/net481/PublicAPI.Shipped.txt | 6 +- .../PublicAPI/net6.0/PublicAPI.Shipped.txt | 6 +- .../net7.0-android/PublicAPI.Shipped.txt | 6 +- .../PublicAPI/net7.0/PublicAPI.Shipped.txt | 6 +- .../net8.0-android/PublicAPI.Shipped.txt | 6 +- .../PublicAPI/net8.0/PublicAPI.Shipped.txt | 6 +- .../netstandard2.0/PublicAPI.Shipped.txt | 6 +- src/PDFtoImage/RenderOptions.cs | 8 +- src/WebConverter/Models/RenderRequest.cs | 2 + src/WebConverter/Pages/Index.razor | 9 +- src/WebConverter/Pages/Index.razor.cs | 3 +- 18 files changed, 174 insertions(+), 93 deletions(-) diff --git a/src/PDFtoImage/Conversion.cs b/src/PDFtoImage/Conversion.cs index 1693c590..28dd7df6 100644 --- a/src/PDFtoImage/Conversion.cs +++ b/src/PDFtoImage/Conversion.cs @@ -325,10 +325,6 @@ public static SKBitmap ToImage(Stream pdfStream, bool leaveOpen = false, string? if (options == default) options = new(); - // correct the width and height for the given dpi - // but only if both width and height are not specified (so the original sizes are corrected) - var correctFromDpi = options.Width == null && options.Height == null; - NativeMethods.FPDF renderFlags = default; if (options.WithAnnotations) @@ -347,16 +343,21 @@ public static SKBitmap ToImage(Stream pdfStream, bool leaveOpen = false, string? if (page >= pdfDocument.PageSizes.Count) throw new ArgumentOutOfRangeException(nameof(page), $"The page number {page} does not exist. Highest page number available is {pdfDocument.PageSizes.Count - 1}."); - var currentWidth = (float?)options.Width; - var currentHeight = (float?)options.Height; - var pageSize = pdfDocument.PageSizes[page]; - - // correct aspect ratio if requested - if (options.WithAspectRatio) - AdjustForAspectRatio(ref currentWidth, ref currentHeight, pageSize); - // Internals.PdfDocument -> Image - return pdfDocument.Render(page, currentWidth ?? pageSize.Width, currentHeight ?? pageSize.Height, options.Dpi, options.Dpi, options.Rotation, renderFlags, options.WithFormFill, correctFromDpi, options.BackgroundColor ?? SKColors.White, options.Bounds, options.UseTiling); + return pdfDocument.Render( + page, + options.Width, + options.Height, + options.Dpi, + options.Dpi, + options.Rotation, + renderFlags, + options.WithFormFill, + options.BackgroundColor ?? SKColors.White, + options.Bounds, + options.UseTiling, + options.WithAspectRatio, + options.DpiRelativeToBounds); } /// @@ -564,10 +565,6 @@ public static IEnumerable ToImages(Stream pdfStream, bool leaveOpen = if (options == default) options = new(); - // correct the width and height for the given dpi - // but only if both width and height are not specified (so the original sizes are corrected) - var correctFromDpi = options.Width == null && options.Height == null; - NativeMethods.FPDF renderFlags = default; if (options.WithAnnotations) @@ -585,16 +582,21 @@ public static IEnumerable ToImages(Stream pdfStream, bool leaveOpen = for (int i = 0; i < pdfDocument.PageSizes.Count; i++) { - var currentWidth = (float?)options.Width; - var currentHeight = (float?)options.Height; - var pageSize = pdfDocument.PageSizes[i]; - - // correct aspect ratio if requested - if (options.WithAspectRatio) - AdjustForAspectRatio(ref currentWidth, ref currentHeight, pageSize); - // Internals.PdfDocument -> Image - yield return pdfDocument.Render(i, currentWidth ?? pageSize.Width, currentHeight ?? pageSize.Height, options.Dpi, options.Dpi, options.Rotation, renderFlags, options.WithFormFill, correctFromDpi, options.BackgroundColor ?? SKColors.White, options.Bounds, options.UseTiling); + yield return pdfDocument.Render( + i, + options.Width, + options.Height, + options.Dpi, + options.Dpi, + options.Rotation, + renderFlags, + options.WithFormFill, + options.BackgroundColor ?? SKColors.White, + options.Bounds, + options.UseTiling, + options.WithAspectRatio, + options.DpiRelativeToBounds); } } @@ -657,10 +659,6 @@ public static async IAsyncEnumerable ToImagesAsync(Stream pdfStream, b if (options == default) options = new(); - // correct the width and height for the given dpi - // but only if both width and height are not specified (so the original sizes are corrected) - var correctFromDpi = options.Width == null && options.Height == null; - NativeMethods.FPDF renderFlags = default; if (options.WithAnnotations) @@ -680,16 +678,22 @@ public static async IAsyncEnumerable ToImagesAsync(Stream pdfStream, b { cancellationToken.ThrowIfCancellationRequested(); - var currentWidth = (float?)options.Width; - var currentHeight = (float?)options.Height; - var pageSize = pdfDocument.PageSizes[i]; - - // correct aspect ratio if requested - if (options.WithAspectRatio) - AdjustForAspectRatio(ref currentWidth, ref currentHeight, pageSize); - // Internals.PdfDocument -> Image - yield return await Task.Run(() => pdfDocument.Render(i, currentWidth ?? pageSize.Width, currentHeight ?? pageSize.Height, options.Dpi, options.Dpi, options.Rotation, renderFlags, options.WithFormFill, correctFromDpi, options.BackgroundColor ?? SKColors.White, options.Bounds, options.UseTiling, cancellationToken), cancellationToken); + yield return await Task.Run(() => pdfDocument.Render( + i, + options.Width, + options.Height, + options.Dpi, + options.Dpi, + options.Rotation, + renderFlags, + options.WithFormFill, + options.BackgroundColor ?? SKColors.White, + options.Bounds, + options.UseTiling, + options.WithAspectRatio, + options.DpiRelativeToBounds, + cancellationToken), cancellationToken); } } #endif @@ -741,17 +745,5 @@ internal static void SaveImpl(Stream stream, SKEncodedImageFormat format, Stream using var bitmap = ToImage(pdfStream, leaveOpen, password, page, options); bitmap.Encode(stream, format, 100); } - - private static void AdjustForAspectRatio(ref float? width, ref float? height, SizeF pageSize) - { - if (width == null && height != null) - { - width = pageSize.Width / pageSize.Height * height.Value; - } - else if (width != null && height == null) - { - height = pageSize.Height / pageSize.Width * width.Value; - } - } } } \ No newline at end of file diff --git a/src/PDFtoImage/IRenderOptions.cs b/src/PDFtoImage/IRenderOptions.cs index 8f5513c8..59fed7b0 100644 --- a/src/PDFtoImage/IRenderOptions.cs +++ b/src/PDFtoImage/IRenderOptions.cs @@ -54,7 +54,7 @@ public interface IRenderOptions SKColor? BackgroundColor { get; init; } /// - /// Specifies the bounds for the page relative to . This can be used for clipping (bounds inside of page) or additional margins (bounds outside of page). + /// Specifies the bounds for the page relative to . This can be used for clipping (bounds inside of page) or additional margins (bounds outside of page). The bound units are relative to the PDF size (at 72 DPI). /// RectangleF? Bounds { get; init; } @@ -62,5 +62,10 @@ public interface IRenderOptions /// Specifies that the PDF should be rendered as several segments and merged into the final image. This can help in cases where the output image is too large, causing corrupted images (e.g. missing text) or crashes. /// bool UseTiling { get; init; } + + /// + /// Specifies that and will be calculated relative to instead of the original PDF. + /// + bool DpiRelativeToBounds { get; init; } } } \ No newline at end of file diff --git a/src/PDFtoImage/Internals/PdfDocument.cs b/src/PDFtoImage/Internals/PdfDocument.cs index 22435dca..ee631a00 100644 --- a/src/PDFtoImage/Internals/PdfDocument.cs +++ b/src/PDFtoImage/Internals/PdfDocument.cs @@ -16,10 +16,10 @@ namespace PDFtoImage.Internals /// /// Provides functionality to render a PDF document. /// - internal sealed class PdfDocument : IDisposable + internal struct PdfDocument : IDisposable { private bool _disposed; - private PdfFile? _file; + private PdfFile _file; /// /// Initializes a new instance of the PdfDocument class with the provided stream. @@ -50,31 +50,53 @@ private PdfDocument(Stream stream, string? password, bool disposeStream) private const int MaxTileWidth = 4000; private const int MaxTileHeight = 4000; - /// - /// Renders a page of the PDF document to an image. - /// - /// Number of the page to render. - /// Width of the rendered image. - /// Height of the rendered image. - /// Horizontal DPI. - /// Vertical DPI. - /// Rotation. - /// Flags used to influence the rendering. - /// Render form fills. - /// Change and depending on the given and . - /// The background color used for the output. - /// Specifies the bounds for the page relative to . This can be used for clipping (bounds inside of page) or additional margins (bounds outside of page). - /// - /// - /// The rendered image. - public SKBitmap Render(int page, float width, float height, float dpiX, float dpiY, PdfRotation rotate, NativeMethods.FPDF flags, bool renderFormFill, bool correctFromDpi, SKColor backgroundColor, RectangleF? bounds, bool useTiling, CancellationToken cancellationToken = default) + public readonly SKBitmap Render(int page, float? requestedWidth, float? requestedHeight, float dpiX, float dpiY, PdfRotation rotate, NativeMethods.FPDF flags, bool renderFormFill, SKColor backgroundColor, RectangleF? bounds, bool useTiling, bool withAspectRatio, bool dpiRelativeToBounds, CancellationToken cancellationToken = default) { if (_disposed) throw new ObjectDisposedException(GetType().Name); + // correct the width and height for the given dpi + // but only if both width and height are not specified (so the original sizes are corrected) + var correctFromDpi = requestedWidth == null && requestedHeight == null; + var originalWidth = PageSizes[page].Width; var originalHeight = PageSizes[page].Height; + if (withAspectRatio && !(dpiRelativeToBounds && bounds.HasValue)) + { + AdjustForAspectRatio(ref requestedWidth, ref requestedHeight, PageSizes[page]); + } + + float width = requestedWidth ?? originalWidth; + float height = requestedHeight ?? originalHeight; + + if (dpiRelativeToBounds && bounds.HasValue) + { + float? boundsWidth = requestedWidth != null ? requestedWidth : null; + float? boundsHeight = requestedHeight != null ? requestedHeight : null; + + if (withAspectRatio) + { + AdjustForAspectRatio(ref boundsWidth, ref boundsHeight, new SizeF(bounds.Value.Width, bounds.Value.Height)); + } + + if (requestedWidth == null) + { + width = boundsWidth ?? bounds.Value.Width; + } + + if (requestedHeight == null) + { + height = boundsHeight ?? bounds.Value.Height; + } + + bounds = new RectangleF( + bounds.Value.X * (width / originalWidth), + bounds.Value.Y * (height / originalHeight), + bounds.Value.Width, + bounds.Value.Height); + } + if (rotate == PdfRotation.Rotate90 || rotate == PdfRotation.Rotate270) { (width, height) = (height, width); @@ -200,6 +222,18 @@ public SKBitmap Render(int page, float width, float height, float dpiX, float dp return bitmap; } + private static void AdjustForAspectRatio(ref float? width, ref float? height, SizeF pageSize) + { + if (width == null && height != null) + { + width = pageSize.Width / pageSize.Height * height.Value; + } + else if (width != null && height == null) + { + height = pageSize.Height / pageSize.Width * width.Value; + } + } + private static SKBitmap RenderSubset(PdfFile file, int page, float width, float height, PdfRotation rotate, NativeMethods.FPDF flags, bool renderFormFill, SKColor backgroundColor, RectangleF? bounds, float originalWidth, float originalHeight, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); @@ -261,8 +295,7 @@ private void Dispose(bool disposing) { if (!_disposed && disposing) { - _file?.Dispose(); - _file = null; + _file.Dispose(); _disposed = true; } diff --git a/src/PDFtoImage/Internals/PdfFile.cs b/src/PDFtoImage/Internals/PdfFile.cs index 3bd22b33..ec3f3bbe 100644 --- a/src/PDFtoImage/Internals/PdfFile.cs +++ b/src/PDFtoImage/Internals/PdfFile.cs @@ -4,7 +4,6 @@ using System.Drawing; using System.IO; using System.Runtime.InteropServices; -using System.Text; namespace PDFtoImage.Internals { @@ -13,7 +12,7 @@ namespace PDFtoImage.Internals #pragma warning disable IDE0056 // Use index operator #pragma warning disable IDE0057 // Use range operator #endif - internal sealed class PdfFile : IDisposable + internal struct PdfFile : IDisposable { private IntPtr _document; private IntPtr _form; @@ -53,7 +52,7 @@ public PdfFile(Stream stream, string? password, bool disposeStream) _disposeStream=disposeStream; } - public bool RenderPDFPageToBitmap(int pageNumber, IntPtr bitmapHandle, int boundsOriginX, int boundsOriginY, int boundsWidth, int boundsHeight, int rotate, NativeMethods.FPDF flags, bool renderFormFill) + public readonly bool RenderPDFPageToBitmap(int pageNumber, IntPtr bitmapHandle, int boundsOriginX, int boundsOriginY, int boundsWidth, int boundsHeight, int rotate, NativeMethods.FPDF flags, bool renderFormFill) { if (_disposed) throw new ObjectDisposedException(GetType().Name); @@ -87,7 +86,7 @@ public List GetPDFDocInfo() return result; } - public SizeF GetPDFDocInfo(int pageNumber) + public readonly SizeF GetPDFDocInfo(int pageNumber) { NativeMethods.FPDF_GetPageSizeByIndex(_document, pageNumber, out double width, out double height); diff --git a/src/PDFtoImage/PublicAPI/monoandroid10.0/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/monoandroid10.0/PublicAPI.Shipped.txt index 73742c61..0f7af661 100644 --- a/src/PDFtoImage/PublicAPI/monoandroid10.0/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/monoandroid10.0/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/PublicAPI/net462/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/net462/PublicAPI.Shipped.txt index 73742c61..0f7af661 100644 --- a/src/PDFtoImage/PublicAPI/net462/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/net462/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/PublicAPI/net471/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/net471/PublicAPI.Shipped.txt index 73742c61..0f7af661 100644 --- a/src/PDFtoImage/PublicAPI/net471/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/net471/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/PublicAPI/net481/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/net481/PublicAPI.Shipped.txt index 73742c61..0f7af661 100644 --- a/src/PDFtoImage/PublicAPI/net481/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/net481/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/PublicAPI/net6.0/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/net6.0/PublicAPI.Shipped.txt index b85c3d45..e242ffc8 100644 --- a/src/PDFtoImage/PublicAPI/net6.0/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/net6.0/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/PublicAPI/net7.0-android/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/net7.0-android/PublicAPI.Shipped.txt index b85c3d45..e242ffc8 100644 --- a/src/PDFtoImage/PublicAPI/net7.0-android/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/net7.0-android/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/PublicAPI/net7.0/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/net7.0/PublicAPI.Shipped.txt index b85c3d45..e242ffc8 100644 --- a/src/PDFtoImage/PublicAPI/net7.0/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/net7.0/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/PublicAPI/net8.0-android/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/net8.0-android/PublicAPI.Shipped.txt index b85c3d45..e242ffc8 100644 --- a/src/PDFtoImage/PublicAPI/net8.0-android/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/net8.0-android/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/PublicAPI/net8.0/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/net8.0/PublicAPI.Shipped.txt index b85c3d45..e242ffc8 100644 --- a/src/PDFtoImage/PublicAPI/net8.0/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/net8.0/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt b/src/PDFtoImage/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt index 73742c61..0f7af661 100644 --- a/src/PDFtoImage/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/PDFtoImage/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt @@ -8,10 +8,12 @@ PDFtoImage.RenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.RenderOptions.Bounds.init -> void PDFtoImage.RenderOptions.Dpi.get -> int PDFtoImage.RenderOptions.Dpi.init -> void +PDFtoImage.RenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.RenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.RenderOptions.Height.get -> int? PDFtoImage.RenderOptions.Height.init -> void PDFtoImage.RenderOptions.RenderOptions() -> void -PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false) -> void +PDFtoImage.RenderOptions.RenderOptions(int Dpi = 300, int? Width = null, int? Height = null, bool WithAnnotations = false, bool WithFormFill = false, bool WithAspectRatio = false, PDFtoImage.PdfRotation Rotation = PDFtoImage.PdfRotation.Rotate0, PDFtoImage.PdfAntiAliasing AntiAliasing = PDFtoImage.PdfAntiAliasing.All, SkiaSharp.SKColor? BackgroundColor = null, System.Drawing.RectangleF? Bounds = null, bool UseTiling = false, bool DpiRelativeToBounds = false) -> void PDFtoImage.RenderOptions.Rotation.get -> PDFtoImage.PdfRotation PDFtoImage.RenderOptions.Rotation.init -> void PDFtoImage.RenderOptions.Width.get -> int? @@ -33,6 +35,8 @@ PDFtoImage.IRenderOptions.Bounds.get -> System.Drawing.RectangleF? PDFtoImage.IRenderOptions.Bounds.init -> void PDFtoImage.IRenderOptions.Dpi.get -> int PDFtoImage.IRenderOptions.Dpi.init -> void +PDFtoImage.IRenderOptions.DpiRelativeToBounds.get -> bool +PDFtoImage.IRenderOptions.DpiRelativeToBounds.init -> void PDFtoImage.IRenderOptions.Height.get -> int? PDFtoImage.IRenderOptions.Height.init -> void PDFtoImage.IRenderOptions.Rotation.get -> PDFtoImage.PdfRotation diff --git a/src/PDFtoImage/RenderOptions.cs b/src/PDFtoImage/RenderOptions.cs index 5bf89daf..36c8e82d 100644 --- a/src/PDFtoImage/RenderOptions.cs +++ b/src/PDFtoImage/RenderOptions.cs @@ -15,8 +15,9 @@ namespace PDFtoImage /// Specifies the rotation at 90 degree intervals. /// Specifies which parts of the PDF should be anti-aliasing for rendering. /// Specifies the background color. Defaults to . - /// Specifies the bounds for the page relative to . This can be used for clipping (bounds inside of page) or additional margins (bounds outside of page). + /// Specifies the bounds for the page relative to . This can be used for clipping (bounds inside of page) or additional margins (bounds outside of page). The bound units are relative to the PDF size (at 72 DPI). /// Specifies that the PDF should be rendered as several segments and merged into the final image. This can help in cases where the output image is too large, causing corrupted images (e.g. missing text) or crashes. + /// Specifies that and will be calculated relative to instead of the original PDF. public readonly record struct RenderOptions( int Dpi = 300, int? Width = null, @@ -28,12 +29,13 @@ public readonly record struct RenderOptions( PdfAntiAliasing AntiAliasing = PdfAntiAliasing.All, SKColor? BackgroundColor = null, RectangleF? Bounds = null, - bool UseTiling = false) : IRenderOptions + bool UseTiling = false, + bool DpiRelativeToBounds = false) : IRenderOptions { /// /// Constructs with default values. /// - public RenderOptions() : this(300, null, null, false, false, false, PdfRotation.Rotate0, PdfAntiAliasing.All, null, null, false) { } + public RenderOptions() : this(300, null, null, false, false, false, PdfRotation.Rotate0, PdfAntiAliasing.All, null, null, false, false) { } } } #if NETSTANDARD || MONOANDROID || NETFRAMEWORK diff --git a/src/WebConverter/Models/RenderRequest.cs b/src/WebConverter/Models/RenderRequest.cs index 9d420452..f4828f00 100644 --- a/src/WebConverter/Models/RenderRequest.cs +++ b/src/WebConverter/Models/RenderRequest.cs @@ -91,6 +91,8 @@ public class RenderRequest : IDisposable public bool UseTiling { get; set; } = true; + public bool DpiRelativeToBounds { get; set; } = false; + public static string GetRotationLocalized(PdfRotation rotation) => rotation switch { PdfRotation.Rotate0 => "0°", diff --git a/src/WebConverter/Pages/Index.razor b/src/WebConverter/Pages/Index.razor index e6270973..8c434954 100644 --- a/src/WebConverter/Pages/Index.razor +++ b/src/WebConverter/Pages/Index.razor @@ -211,7 +211,7 @@ This option can help with rendering problems (e.g. missing text) at very high re -
+
@@ -222,6 +222,13 @@ This option can help with rendering problems (e.g. missing text) at very high re
+ +
+
+ + +
+
diff --git a/src/WebConverter/Pages/Index.razor.cs b/src/WebConverter/Pages/Index.razor.cs index 9cf03e30..594f0e2b 100644 --- a/src/WebConverter/Pages/Index.razor.cs +++ b/src/WebConverter/Pages/Index.razor.cs @@ -178,7 +178,8 @@ await Task.Factory.StartNew(() => AntiAliasing: antiAliasing, BackgroundColor: backgroundColor, Bounds: Model.UseBounds ? new RectangleF(Model.BoundsX, Model.BoundsY, Model.BoundsWidth, Model.BoundsHeight) : null, - UseTiling: Model.UseTiling + UseTiling: Model.UseTiling, + DpiRelativeToBounds: Model.DpiRelativeToBounds ) ); encodeSuccess = bitmap!.Encode(Model.Output, Model.Format, Model.Quality);