#region PDFsharp - A .NET library for processing PDF // // Authors: // Stefan Lange // // Copyright (c) 2005-2016 empira Software GmbH, Cologne Area (Germany) // // http://www.PdfSharp.com // http://sourceforge.net/projects/pdfsharp // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. #endregion using System; using System.Diagnostics; using System.IO; using PdfSharpCore.Pdf.IO; using PdfSharpCore.Pdf.Advanced; using MigraDocCore.DocumentObjectModel.MigraDoc.DocumentObjectModel.Shapes; using PdfSharpCore.Pdf.IO.enums; using static MigraDocCore.DocumentObjectModel.MigraDoc.DocumentObjectModel.Shapes.ImageSource; using PdfSharpCore.Utils; using SixLabors.ImageSharp.PixelFormats; namespace PdfSharpCore.Drawing { [Flags] internal enum XImageState { UsedInDrawingContext = 0x00000001, StateMask = 0x0000FFFF, } /// /// Defines an object used to draw image files (bmp, png, jpeg, gif) and PDF forms. /// An abstract base class that provides functionality for the Bitmap and Metafile descended classes. /// public class XImage : IDisposable { // The hierarchy is adapted to WPF/Silverlight/WinRT // // XImage <-- ImageSource // XForm // PdfForm // XBitmapSource <-- BitmapSource // XBitmapImage <-- BitmapImage // ??? //public bool Disposed //{ // get { return _disposed; } // set { _disposed = value; } //} /// /// Initializes a new instance of the class. /// protected XImage() { } // Useful stuff here: http://stackoverflow.com/questions/350027/setting-wpf-image-source-in-code XImage(string path) { if (ImageSource.ImageSourceImpl == null) ImageSource.ImageSourceImpl = new ImageSharpImageSource(); _source = ImageSource.FromFile(path); Initialize(); } XImage(IImageSource imageSource) { _source = imageSource; _path = _source.Name; Initialize(); } XImage(Func stream) { // Create a dummy unique path. _path = "*" + Guid.NewGuid().ToString("B"); if (ImageSource.ImageSourceImpl == null) ImageSource.ImageSourceImpl = new ImageSharpImageSource(); _source = ImageSource.FromStream(_path, stream); Initialize(); } XImage(Func data) { // Create a dummy unique path. _path = "*" + Guid.NewGuid().ToString("B"); _source = ImageSource.FromBinary(_path, data); Initialize(); } /// /// Creates an image from the specified file. /// For non-pdf files, this requires that an instance of an implementation of be set on the `ImageSource.ImageSourceImpl` property. /// For .NetCore apps, if this property is null at this point, then with Pixel Type is used /// /// The path to a BMP, PNG, GIF, JPEG, TIFF, or PDF file. public static XImage FromFile(string path) { return FromFile(path, PdfReadAccuracy.Strict); } /// /// Creates an image from the specified file. /// For non-pdf files, this requires that an instance of an implementation of be set on the `ImageSource.ImageSourceImpl` property. /// For .NetCore apps, if this property is null at this point, then with Pixel Type is used /// /// The path to a BMP, PNG, GIF, JPEG, TIFF, or PDF file. /// Moderate allows for broken references when using a PDF file. public static XImage FromFile(string path, PdfReadAccuracy accuracy) { if (PdfReader.TestPdfFile(path) > 0) return new XPdfForm(path, accuracy); return new XImage(path); } /// /// Creates an image from the specified stream.
/// For non-pdf files, this requires that an instance of an implementation of be set on the `ImageSource.ImageSourceImpl` property. /// For .NetCore apps, if this property is null at this point, then with Pixel Type is used /// Silverlight supports PNG and JPEF only. ///
/// The stream containing a BMP, PNG, GIF, JPEG, TIFF, or PDF file. public static XImage FromStream(Func stream) { if (stream == null) throw new ArgumentNullException("stream"); // TODO: Check PDF stream. //if (PdfReader.TestPdfFile(path) > 0) // return new XPdfForm(path); return new XImage(stream); } public static XImage FromImageSource(IImageSource imageSouce) { return new XImage(imageSouce); } /// /// Tests if a file exist. Supports PDF files with page number suffix. /// /// The path to a BMP, PNG, GIF, JPEG, TIFF, or PDF file. public static bool ExistsFile(string path) { // Support for "base64:" pseudo protocol is a MigraDoc feature, currently completely implemented in MigraDoc files. TODO: Does support for "base64:" make sense for PDFsharp? Probably not as PDFsharp can handle images from streams. //if (path.StartsWith("base64:")) // The Image is stored in the string here, so the file exists. // return true; if (PdfReader.TestPdfFile(path) > 0) return true; return false; } internal XImageState XImageState { get { return _xImageState; } set { _xImageState = value; } } XImageState _xImageState; internal void Initialize() { if (_source != null) { //We always get a jpeg from an image source _format = _source.Transparent ? XImageFormat.Png : XImageFormat.Jpeg; } } public MemoryStream AsJpeg() { var ms = new MemoryStream(); _source.SaveAsJpeg(ms); ms.Position = 0; return ms; } public MemoryStream AsBitmap() { var ms = new MemoryStream(); _source.SaveAsPdfBitmap(ms); ms.Position = 0; return ms; } /// /// Under construction /// public void Dispose() { Dispose(true); //GC.SuppressFinalize(this); } /// /// Disposes underlying GDI+ object. /// protected virtual void Dispose(bool disposing) { if (!_disposed) _disposed = true; } bool _disposed; /// /// Gets the width of the image in point. /// public virtual double PointWidth { get { return _source.Width * 72 / 96.0; } } /// /// Gets the height of the image in point. /// public virtual double PointHeight { get { return _source.Height * 72 / 96.0; } } /// /// Gets the width of the image in pixels. /// public virtual int PixelWidth { get { return _source.Width; } } /// /// Gets the height of the image in pixels. /// public virtual int PixelHeight { get { return _source.Height; } } /// /// Gets the size in point of the image. /// public virtual XSize Size { get { return new XSize(PointWidth, PointHeight); } } /// /// Gets the horizontal resolution of the image. /// public virtual double HorizontalResolution { get { return 96; } } /// /// Gets the vertical resolution of the image. /// public virtual double VerticalResolution { get { return 96; } } /// /// Gets or sets a flag indicating whether image interpolation is to be performed. /// public virtual bool Interpolate { get { return _interpolate; } set { _interpolate = value; } } bool _interpolate = true; /// /// Gets the format of the image. /// public XImageFormat Format { get { return _format; } } XImageFormat _format; internal void AssociateWithGraphics(XGraphics gfx) { if (_associatedGraphics != null) throw new InvalidOperationException("XImage already associated with XGraphics."); _associatedGraphics = null; } internal void DisassociateWithGraphics() { if (_associatedGraphics == null) throw new InvalidOperationException("XImage not associated with XGraphics."); _associatedGraphics.DisassociateImage(); Debug.Assert(_associatedGraphics == null); } internal void DisassociateWithGraphics(XGraphics gfx) { if (_associatedGraphics != gfx) throw new InvalidOperationException("XImage not associated with XGraphics."); _associatedGraphics = null; } internal XGraphics AssociatedGraphics { get { return _associatedGraphics; } set { _associatedGraphics = value; } } XGraphics _associatedGraphics; /// /// If path starts with '*' the image is created from a stream and the path is a GUID. /// internal string _path; /// /// Cache PdfImageTable.ImageSelector to speed up finding the right PdfImage /// if this image is used more than once. /// internal PdfImageTable.ImageSelector _selector; private IImageSource _source; } }