瀏覽代碼

Documentation: Image

Marcin Ziąbek 2 年之前
父節點
當前提交
2b0ef38937

+ 5 - 0
Source/QuestPDF/Elements/DynamicImage.cs

@@ -7,6 +7,11 @@ using SkiaSharp;
 
 
 namespace QuestPDF.Elements
 namespace QuestPDF.Elements
 {
 {
+    /// <summary>
+    /// Generates an image based on the given resolution.
+    /// </summary>
+    /// <param name="size">Desired resolution of the image in pixels.</param>
+    /// <returns>An image in PNG, JPEG, or WEBP image format returned as byte array.</returns>
     public delegate byte[] GenerateDynamicImageDelegate(ImageSize size);
     public delegate byte[] GenerateDynamicImageDelegate(ImageSize size);
     
     
     internal class DynamicImage : Element
     internal class DynamicImage : Element

+ 87 - 28
Source/QuestPDF/Fluent/ImageExtensions.cs

@@ -7,6 +7,37 @@ using SkiaSharp;
 
 
 namespace QuestPDF.Fluent
 namespace QuestPDF.Fluent
 {
 {
+    public class DynamicImageDescriptor
+    {
+        private Elements.DynamicImage ImageElement { get; }
+        
+        internal DynamicImageDescriptor(Elements.DynamicImage imageElement)
+        {
+            ImageElement = imageElement;
+        }
+        
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.useOriginalImage"]/*' />
+        public DynamicImageDescriptor UseOriginalImage(bool value = true)
+        {
+            ImageElement.UseOriginalImage = value;
+            return this;
+        }
+        
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.rasterDPI"]/*' />
+        public DynamicImageDescriptor WithRasterDpi(int dpi)
+        {
+            ImageElement.TargetDpi = dpi;
+            return this;
+        }
+
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.compressionQuality"]/*' />
+        public DynamicImageDescriptor WithCompressionQuality(ImageCompressionQuality quality)
+        {
+            ImageElement.CompressionQuality = quality;
+            return this;
+        }
+    }
+    
     public class ImageDescriptor
     public class ImageDescriptor
     {
     {
         private Elements.Image ImageElement { get; }
         private Elements.Image ImageElement { get; }
@@ -22,33 +53,21 @@ namespace QuestPDF.Fluent
             ImageAspectRatio = imageSize.Width / (float)imageSize.Height;
             ImageAspectRatio = imageSize.Width / (float)imageSize.Height;
         }
         }
         
         
-        /// <summary>
-        /// When enabled, the library will not attempt to resize the image to fit the target DPI, nor save it with target image quality.
-        /// </summary>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.useOriginalImage"]/*' />
         public ImageDescriptor UseOriginalImage(bool value = true)
         public ImageDescriptor UseOriginalImage(bool value = true)
         {
         {
             ImageElement.UseOriginalImage = value;
             ImageElement.UseOriginalImage = value;
             return this;
             return this;
         }
         }
         
         
-        /// <summary>
-        /// 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>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.rasterDPI"]/*' />
         public ImageDescriptor WithRasterDpi(int dpi)
         public ImageDescriptor WithRasterDpi(int dpi)
         {
         {
             ImageElement.TargetDpi = dpi;
             ImageElement.TargetDpi = dpi;
             return this;
             return this;
         }
         }
 
 
-        /// <summary>
-        /// Encoding quality controls the trade-off between size and quality.
-        /// When the image is opaque, it will be encoded using the JPEG format with the selected quality setting.
-        /// When the image contains an alpha channel, it is always encoded using the PNG format and this option is ignored.
-        /// The default value is "very high quality".
-        /// </summary>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.compressionQuality"]/*' />
         public ImageDescriptor WithCompressionQuality(ImageCompressionQuality quality)
         public ImageDescriptor WithCompressionQuality(ImageCompressionQuality quality)
         {
         {
             ImageElement.CompressionQuality = quality;
             ImageElement.CompressionQuality = quality;
@@ -58,7 +77,7 @@ namespace QuestPDF.Fluent
         #region Aspect Ratio
         #region Aspect Ratio
         
         
         /// <summary>
         /// <summary>
-        /// The image scales to take the entire available width. Default.
+        /// Scales the image to fill the full width of its container. This is the default behavior.
         /// </summary>
         /// </summary>
         public ImageDescriptor FitWidth()
         public ImageDescriptor FitWidth()
         {
         {
@@ -66,7 +85,8 @@ namespace QuestPDF.Fluent
         }
         }
         
         
         /// <summary>
         /// <summary>
-        /// The images scales to take the entire available height. Good in conjunction with constraining elements.
+        /// <para>The image stretches vertically to fit the full available height.</para>
+        /// <para>Often used with height-constraining elements such as: <see cref="ConstrainedExtensions.Height">Height</see>, <see cref="ConstrainedExtensions.MaxHeight">MaxHeight</see>, etc.</para>
         /// </summary>
         /// </summary>
         public ImageDescriptor FitHeight()
         public ImageDescriptor FitHeight()
         {
         {
@@ -74,20 +94,21 @@ namespace QuestPDF.Fluent
         }
         }
         
         
         /// <summary>
         /// <summary>
-        /// This is the combination of both of the FitWidth and the FitHeight options. 
-        /// The element scales to occupy the entire available area while preserving its aspect ratio.
-        /// This means that sometimes it occupies the entire width and sometimes the entire height.
-        /// This is the safest option.
+        /// Combines the FitWidth and FitHeight settings.
+        /// The image resizes itself to utilize all available space, preserving its aspect ratio.
+        /// It will either fill the width or height based on the container's dimensions.
         /// </summary>
         /// </summary>
+        /// <remarks>
+        /// An optimal and safe choice.
+        /// </remarks>
         public ImageDescriptor FitArea()
         public ImageDescriptor FitArea()
         {
         {
             return SetAspectRatio(AspectRatioOption.FitArea);
             return SetAspectRatio(AspectRatioOption.FitArea);
         }
         }
         
         
         /// <summary>
         /// <summary>
-        /// The image resizes itself to occupy the entire available space.
-        /// It does not preserve proportions.
-        /// The image may look incorrectly scaled, and is not desired in most of the cases.
+        /// The image adjusts to fill all the available space, disregarding its original proportions.
+        /// This can lead to distorted scaling and is generally not recommended for most scenarios.
         /// </summary>
         /// </summary>
         public ImageDescriptor FitUnproportionally()
         public ImageDescriptor FitUnproportionally()
         {
         {
@@ -107,24 +128,49 @@ namespace QuestPDF.Fluent
     
     
     public static class ImageExtensions
     public static class ImageExtensions
     {
     {
+        /// <summary>
+        /// Draws an image by decoding it from a provided byte array.
+        /// <a href="https://www.questpdf.com/api-reference/image.html">Learn more</a>
+        /// </summary>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.remarks"]/*' />
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.descriptor"]/*' />
         public static ImageDescriptor Image(this IContainer parent, byte[] imageData)
         public static ImageDescriptor Image(this IContainer parent, byte[] imageData)
         {
         {
             var image = Infrastructure.Image.FromBinaryData(imageData);
             var image = Infrastructure.Image.FromBinaryData(imageData);
             return parent.Image(image);
             return parent.Image(image);
         }
         }
         
         
+        /// <summary>
+        /// Draws the image loaded from a file located at the provided path.
+        /// <a href="https://www.questpdf.com/api-reference/image.html">Learn more</a>
+        /// </summary>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.remarks"]/*' />
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.descriptor"]/*' />
         public static ImageDescriptor Image(this IContainer parent, string filePath)
         public static ImageDescriptor Image(this IContainer parent, string filePath)
         {
         {
             var image = Infrastructure.Image.FromFile(filePath);
             var image = Infrastructure.Image.FromFile(filePath);
             return parent.Image(image);
             return parent.Image(image);
         }
         }
         
         
+        /// <summary>
+        /// Draws the image loaded from a stream.
+        /// <a href="https://www.questpdf.com/api-reference/image.html">Learn more</a>
+        /// </summary>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.remarks"]/*' />
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.descriptor"]/*' />
         public static ImageDescriptor Image(this IContainer parent, Stream fileStream)
         public static ImageDescriptor Image(this IContainer parent, Stream fileStream)
         {
         {
             var image = Infrastructure.Image.FromStream(fileStream);
             var image = Infrastructure.Image.FromStream(fileStream);
             return parent.Image(image);
             return parent.Image(image);
         }
         }
         
         
+        /// <summary>
+        /// Draws the <see cref="Infrastructure.Image" /> object. Allows to optimize the generation process.
+        /// <br />
+        /// <a href="https://www.questpdf.com/api-reference/image.html">Learn more</a>
+        /// </summary>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.remarks"]/*' />
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.descriptor"]/*' />
         public static ImageDescriptor Image(this IContainer parent, Infrastructure.Image image)
         public static ImageDescriptor Image(this IContainer parent, Infrastructure.Image image)
         {
         {
             if (image == null)
             if (image == null)
@@ -143,13 +189,26 @@ namespace QuestPDF.Fluent
             parent.Element(aspectRationElement);
             parent.Element(aspectRationElement);
             return new ImageDescriptor(imageElement, aspectRationElement).FitWidth();
             return new ImageDescriptor(imageElement, aspectRationElement).FitWidth();
         }
         }
-
-        public static void Image(this IContainer element, GenerateDynamicImageDelegate dynamicImageSource)
+        
+        /// <summary>
+        /// Renders an image of dynamic size dictated by the document layout constraints.
+        /// </summary>
+        /// <remarks>
+        /// Ideal for generating pixel-perfect images that might lose quality upon scaling, such as maps or charts.
+        /// </remarks>
+        /// <param name="dynamicImageSource">
+        /// A delegate that requests an image of desired resolution calculated based on target physical image size and provided DPI.
+        /// </param>
+        /// <returns>A descriptor for adjusting image attributes like scaling behavior, compression quality, and resolution.</returns>
+        public static DynamicImageDescriptor Image(this IContainer element, GenerateDynamicImageDelegate dynamicImageSource)
         {
         {
-            element.Element(new DynamicImage
+            var dynamicImage = new DynamicImage
             {
             {
                 Source = dynamicImageSource
                 Source = dynamicImageSource
-            });
+            };
+            
+            element.Element(dynamicImage);
+            return new DynamicImageDescriptor(dynamicImage);
         }
         }
         
         
         #region Obsolete
         #region Obsolete

+ 24 - 0
Source/QuestPDF/Infrastructure/Image.cs

@@ -14,6 +14,15 @@ namespace QuestPDF.Infrastructure
         internal ImageCompressionQuality CompressionQuality { get; set; }
         internal ImageCompressionQuality CompressionQuality { get; set; }
     }
     }
     
     
+    /// <summary>
+    /// <para>Caches the image in local memory for efficient reuse.</para>
+    /// <para>Optimizes the generation process, especially:</para>
+    /// <para>- For images repeated in a single document to enhance performance and reduce output file size (e.g., an image used as list bullet icon).</para>
+    /// <para>- When an image appears on multiple document types for increased generation performance (e.g., a company logo).</para>
+    /// </summary>
+    /// <remarks>
+    /// This class is thread safe.
+    /// </remarks>
     public class Image
     public class Image
     {
     {
         internal SKImage SkImage { get; }
         internal SKImage SkImage { get; }
@@ -61,6 +70,11 @@ namespace QuestPDF.Infrastructure
             return new Image(image);
             return new Image(image);
         }
         }
 
 
+        /// <summary>
+        /// Loads the image from binary data.
+        /// <a href="https://www.questpdf.com/api-reference/image.html">Learn more</a>
+        /// </summary>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.remarks"]/*' />
         public static Image FromBinaryData(byte[] imageData)
         public static Image FromBinaryData(byte[] imageData)
         {
         {
             var image = SKImage.FromEncodedData(imageData);
             var image = SKImage.FromEncodedData(imageData);
@@ -71,6 +85,11 @@ namespace QuestPDF.Infrastructure
             return new Image(image);
             return new Image(image);
         }
         }
 
 
+        /// <summary>
+        /// Loads the image from a file with specified path.
+        /// <a href="https://www.questpdf.com/api-reference/image.html">Learn more</a>
+        /// </summary>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.remarks"]/*' />
         public static Image FromFile(string filePath)
         public static Image FromFile(string filePath)
         {
         {
             var image = SKImage.FromEncodedData(filePath);
             var image = SKImage.FromEncodedData(filePath);
@@ -85,6 +104,11 @@ namespace QuestPDF.Infrastructure
             return new Image(image);
             return new Image(image);
         }
         }
 
 
+        /// <summary>
+        /// Loads the image from a stream.
+        /// <a href="https://www.questpdf.com/api-reference/image.html">Learn more</a>
+        /// </summary>
+        /// <include file='../Resources/Documentation.xml' path='documentation/doc[@for="image.remarks"]/*' />
         public static Image FromStream(Stream fileStream)
         public static Image FromStream(Stream fileStream)
         {
         {
             var image = SKImage.FromEncodedData(fileStream);
             var image = SKImage.FromEncodedData(fileStream);

+ 6 - 6
Source/QuestPDF/Infrastructure/ImageCompressionQuality.cs

@@ -3,32 +3,32 @@
     public enum ImageCompressionQuality
     public enum ImageCompressionQuality
     {
     {
         /// <summary>
         /// <summary>
-        /// JPEG format with compression set to 100 out of 100
+        /// JPEG format with target quality set to 100 out of 100
         /// </summary>
         /// </summary>
         Best,
         Best,
 
 
         /// <summary>
         /// <summary>
-        /// JPEG format with compression set to 90 out of 100
+        /// JPEG format with target quality set to 90 out of 100
         /// </summary>
         /// </summary>
         VeryHigh,
         VeryHigh,
 
 
         /// <summary>
         /// <summary>
-        /// JPEG format with compression set to 75 out of 100
+        /// JPEG format with target quality set to 75 out of 100
         /// </summary>
         /// </summary>
         High,
         High,
 
 
         /// <summary>
         /// <summary>
-        /// JPEG format with compression set to 50 out of 100
+        /// JPEG format with target quality set to 50 out of 100
         /// </summary>
         /// </summary>
         Medium,
         Medium,
 
 
         /// <summary>
         /// <summary>
-        /// JPEG format with compression set to 25 out of 100
+        /// JPEG format with target quality set to 25 out of 100
         /// </summary>
         /// </summary>
         Low,
         Low,
 
 
         /// <summary>
         /// <summary>
-        /// JPEG format with compression set to 10 out of 100
+        /// JPEG format with target quality set to 10 out of 100
         /// </summary>
         /// </summary>
         VeryLow
         VeryLow
     }
     }

+ 4 - 0
Source/QuestPDF/Infrastructure/ImageGenerationSettings.cs

@@ -17,8 +17,12 @@ namespace QuestPDF.Infrastructure
 
 
         /// <summary>
         /// <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 the document will be rasterized. This parameter controls the resolution of produced images.
+        /// Higher DPI results in superior image quality but may increase the output file size.
         /// Default value is 288.
         /// Default value is 288.
         /// </summary>
         /// </summary>
+        /// <example>
+        /// Consider a document of dimensions 3x4 inches. Using a DPI value of 300, the final image resolution translates to 900x1200 pixels.
+        /// </example>
         public int RasterDpi { get; set; } = DocumentSettings.DefaultRasterDpi * 4;
         public int RasterDpi { get; set; } = DocumentSettings.DefaultRasterDpi * 4;