using System; using System.IO; using System.Net; using System.Text; using System.Runtime.CompilerServices; using System.Collections; using System.util; using System.Reflection; using iTextSharp.text.pdf; using iTextSharp.text.factories; using iTextSharp.text.pdf.codec; /* * $Id: Image.cs,v 1.28 2008/05/13 11:25:11 psoares33 Exp $ * * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ namespace iTextSharp.text { /// /// An Image is the representation of a graphic element (JPEG, PNG or GIF) /// that has to be inserted into the document /// /// /// public abstract class Image : Rectangle { // static membervariables (concerning the presence of borders) /// this is a kind of image Element. public const int DEFAULT = 0; /// this is a kind of image Element. public const int RIGHT_ALIGN = 2; /// this is a kind of image Element. public const int LEFT_ALIGN = 0; /// this is a kind of image Element. public const int MIDDLE_ALIGN = 1; /// this is a kind of image Element. public const int TEXTWRAP = 4; /// this is a kind of image Element. public const int UNDERLYING = 8; /// This represents a coordinate in the transformation matrix. public const int AX = 0; /// This represents a coordinate in the transformation matrix. public const int AY = 1; /// This represents a coordinate in the transformation matrix. public const int BX = 2; /// This represents a coordinate in the transformation matrix. public const int BY = 3; /// This represents a coordinate in the transformation matrix. public const int CX = 4; /// This represents a coordinate in the transformation matrix. public const int CY = 5; /// This represents a coordinate in the transformation matrix. public const int DX = 6; /// This represents a coordinate in the transformation matrix. public const int DY = 7; /** type of image */ public const int ORIGINAL_NONE = 0; /** type of image */ public const int ORIGINAL_JPEG = 1; /** type of image */ public const int ORIGINAL_PNG = 2; /** type of image */ public const int ORIGINAL_GIF = 3; /** type of image */ public const int ORIGINAL_BMP = 4; /** type of image */ public const int ORIGINAL_TIFF = 5; /** type of image */ public const int ORIGINAL_WMF = 6; /** type of image */ public const int ORIGINAL_JPEG2000 = 8; /** Image color inversion */ protected bool invert = false; /// The imagetype. protected int type; /// The URL of the image. protected Uri url; /// The raw data of the image. protected byte[] rawData; /// The template to be treated as an image. protected PdfTemplate[] template = new PdfTemplate[1]; /// The alignment of the Image. protected int alignment; /// Text that can be shown instead of the image. protected string alt; /// This is the absolute X-position of the image. protected float absoluteX = float.NaN; /// This is the absolute Y-position of the image. protected float absoluteY = float.NaN; /// This is the width of the image without rotation. protected float plainWidth; /// This is the width of the image without rotation. protected float plainHeight; /// This is the scaled width of the image taking rotation into account. protected float scaledWidth; /// This is the original height of the image taking rotation into account. protected float scaledHeight; /// This is the rotation of the image. protected float rotationRadians; /// this is the colorspace of a jpeg-image. protected int colorspace = -1; /// this is the bits per component of the raw image. It also flags a CCITT image. protected int bpc = 1; /// this is the transparency information of the raw image protected int[] transparency; // for the moment these variables are only used for Images in class Table // code contributed by Pelikan Stephan /** the indentation to the left. */ protected float indentationLeft = 0; /** the indentation to the right. */ protected float indentationRight = 0; // serial stamping protected long mySerialId = GetSerialId(); static object serialId = 0L; /// Holds value of property dpiX. protected int dpiX = 0; /// Holds value of property dpiY. protected int dpiY = 0; protected bool mask = false; protected Image imageMask; /// Holds value of property interpolation. protected bool interpolation; /// if the annotation is not null the image will be clickable. protected Annotation annotation = null; /// ICC Profile attached protected ICC_Profile profile = null; /** Holds value of property deflated. */ protected bool deflated = false; private PdfDictionary additional = null; /** Holds value of property smask. */ private bool smask; /** Holds value of property XYRatio. */ private float xyRatio = 0; /** Holds value of property originalType. */ protected int originalType = ORIGINAL_NONE; /** Holds value of property originalData. */ protected byte[] originalData; /** The spacing before the image. */ protected float spacingBefore; /** The spacing after the image. */ protected float spacingAfter; /** * Holds value of property widthPercentage. */ private float widthPercentage = 100; protected IPdfOCG layer; /** * Holds value of property initialRotation. */ private float initialRotation; private PdfIndirectReference directReference; // constructors /// /// Constructs an Image-object, using an url. /// /// the URL where the image can be found. public Image(Uri url) : base(0, 0) { this.url = url; this.alignment = DEFAULT; rotationRadians = 0; } /// /// Constructs an Image object duplicate. /// /// another Image object. public Image(Image image) : base(image) { this.type = image.type; this.url = image.url; this.alignment = image.alignment; this.alt = image.alt; this.absoluteX = image.absoluteX; this.absoluteY = image.absoluteY; this.plainWidth = image.plainWidth; this.plainHeight = image.plainHeight; this.scaledWidth = image.scaledWidth; this.scaledHeight = image.scaledHeight; this.rotationRadians = image.rotationRadians; this.indentationLeft = image.indentationLeft; this.indentationRight = image.indentationRight; this.colorspace = image.colorspace; this.rawData = image.rawData; this.template = image.template; this.bpc = image.bpc; this.transparency = image.transparency; this.mySerialId = image.mySerialId; this.invert = image.invert; this.dpiX = image.dpiX; this.dpiY = image.dpiY; this.mask = image.mask; this.imageMask = image.imageMask; this.interpolation = image.interpolation; this.annotation = image.annotation; this.profile = image.profile; this.deflated = image.deflated; this.additional = image.additional; this.smask = image.smask; this.XYRatio = image.XYRatio; this.originalData = image.originalData; this.originalType = image.originalType; this.spacingAfter = image.spacingAfter; this.spacingBefore = image.spacingBefore; this.widthPercentage = image.widthPercentage; this.layer = image.layer; this.initialRotation = image.initialRotation; this.directReference = image.directReference; } /// /// Gets an instance of an Image. /// /// an Image /// an object of type Gif, Jpeg or Png public static Image GetInstance(Image image) { if (image == null) return null; return (Image)image.GetType().GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[] {typeof(Image)}, null).Invoke(new object[] {image}); } /// /// Gets an instance of an Image. /// /// an URL /// an object of type Gif, Jpeg or Png public static Image GetInstance(Uri url) { Stream istr = null; try { WebRequest w = WebRequest.Create(url); istr = w.GetResponse().GetResponseStream(); int c1 = istr.ReadByte(); int c2 = istr.ReadByte(); int c3 = istr.ReadByte(); int c4 = istr.ReadByte(); istr.Close(); istr = null; if (c1 == 'G' && c2 == 'I' && c3 == 'F') { GifImage gif = new GifImage(url); Image img = gif.GetImage(1); return img; } if (c1 == 0xFF && c2 == 0xD8) { return new Jpeg(url); } if (c1 == 0x00 && c2 == 0x00 && c3 == 0x00 && c4 == 0x0c) { return new Jpeg2000(url); } if (c1 == 0xff && c2 == 0x4f && c3 == 0xff && c4 == 0x51) { return new Jpeg2000(url); } if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1] && c3 == PngImage.PNGID[2] && c4 == PngImage.PNGID[3]) { Image img = PngImage.GetImage(url); return img; } if (c1 == 0xD7 && c2 == 0xCD) { Image img = new ImgWMF(url); return img; } if (c1 == 'B' && c2 == 'M') { Image img = BmpImage.GetImage(url); return img; } if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42) || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { RandomAccessFileOrArray ra = null; try { if (url.IsFile) { String file = url.LocalPath; ra = new RandomAccessFileOrArray(file); } else ra = new RandomAccessFileOrArray(url); Image img = TiffImage.GetTiffImage(ra, 1); img.url = url; return img; } finally { if (ra != null) ra.Close(); } } throw new IOException(url.ToString() + " is not a recognized imageformat."); } finally { if (istr != null) { istr.Close(); } } } public static Image GetInstance(Stream s) { byte[] a = RandomAccessFileOrArray.InputStreamToArray(s); s.Close(); return GetInstance(a); } /// /// Gets an instance of an Image. /// /// a byte array /// an object of type Gif, Jpeg or Png public static Image GetInstance(byte[] imgb) { int c1 = imgb[0]; int c2 = imgb[1]; int c3 = imgb[2]; int c4 = imgb[3]; if (c1 == 'G' && c2 == 'I' && c3 == 'F') { GifImage gif = new GifImage(imgb); return gif.GetImage(1); } if (c1 == 0xFF && c2 == 0xD8) { return new Jpeg(imgb); } if (c1 == 0x00 && c2 == 0x00 && c3 == 0x00 && c4 == 0x0c) { return new Jpeg2000(imgb); } if (c1 == 0xff && c2 == 0x4f && c3 == 0xff && c4 == 0x51) { return new Jpeg2000(imgb); } if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1] && c3 == PngImage.PNGID[2] && c4 == PngImage.PNGID[3]) { return PngImage.GetImage(imgb); } if (c1 == 0xD7 && c2 == 0xCD) { return new ImgWMF(imgb); } if (c1 == 'B' && c2 == 'M') { return BmpImage.GetImage(imgb); } if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42) || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { RandomAccessFileOrArray ra = null; try { ra = new RandomAccessFileOrArray(imgb); Image img = TiffImage.GetTiffImage(ra, 1); if (img.OriginalData == null) img.OriginalData = imgb; return img; } finally { if (ra != null) ra.Close(); } } throw new IOException("The byte array is not a recognized imageformat."); } /// /// Converts a .NET image to a Native(PNG, JPG, GIF, WMF) image /// /// /// /// public static Image GetInstance(System.Drawing.Image image, System.Drawing.Imaging.ImageFormat format) { MemoryStream ms = new MemoryStream(); image.Save(ms, format); return GetInstance(ms.ToArray()); } /// /// Gets an instance of an Image from a System.Drwaing.Image. /// /// the System.Drawing.Image to convert /// /// if different from null the transparency /// pixels are replaced by this color /// /// if true the image is treated as black and white /// an object of type ImgRaw public static Image GetInstance(System.Drawing.Image image, Color color, bool forceBW) { System.Drawing.Bitmap bm = (System.Drawing.Bitmap)image; int w = bm.Width; int h = bm.Height; int pxv = 0; if (forceBW) { int byteWidth = (w / 8) + ((w & 7) != 0 ? 1 : 0); byte[] pixelsByte = new byte[byteWidth * h]; int index = 0; int size = h * w; int transColor = 1; if (color != null) { transColor = (color.R + color.G + color.B < 384) ? 0 : 1; } int[] transparency = null; int cbyte = 0x80; int wMarker = 0; int currByte = 0; if (color != null) { for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { int alpha = bm.GetPixel(i, j).A; if (alpha < 250) { if (transColor == 1) currByte |= cbyte; } else { if ((bm.GetPixel(i, j).ToArgb() & 0x888) != 0) currByte |= cbyte; } cbyte >>= 1; if (cbyte == 0 || wMarker + 1 >= w) { pixelsByte[index++] = (byte)currByte; cbyte = 0x80; currByte = 0; } ++wMarker; if (wMarker >= w) wMarker = 0; } } } else { for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { if (transparency == null) { int alpha = bm.GetPixel(i, j).A; if (alpha == 0) { transparency = new int[2]; transparency[0] = transparency[1] = ((bm.GetPixel(i, j).ToArgb() & 0x888) != 0) ? 1 : 0; } } if ((bm.GetPixel(i, j).ToArgb() & 0x888) != 0) currByte |= cbyte; cbyte >>= 1; if (cbyte == 0 || wMarker + 1 >= w) { pixelsByte[index++] = (byte)currByte; cbyte = 0x80; currByte = 0; } ++wMarker; if (wMarker >= w) wMarker = 0; } } } return Image.GetInstance(w, h, 1, 1, pixelsByte, transparency); } else { byte[] pixelsByte = new byte[w * h * 3]; byte[] smask = null; int index = 0; int size = h * w; int red = 255; int green = 255; int blue = 255; if (color != null) { red = color.R; green = color.G; blue = color.B; } int[] transparency = null; if (color != null) { for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { int alpha = (bm.GetPixel(i, j).ToArgb() >> 24) & 0xff; if (alpha < 250) { pixelsByte[index++] = (byte) red; pixelsByte[index++] = (byte) green; pixelsByte[index++] = (byte) blue; } else { pxv = bm.GetPixel(i, j).ToArgb(); pixelsByte[index++] = (byte) ((pxv >> 16) & 0xff); pixelsByte[index++] = (byte) ((pxv >> 8) & 0xff); pixelsByte[index++] = (byte) ((pxv) & 0xff); } } } } else { int transparentPixel = 0; smask = new byte[w * h]; bool shades = false; int smaskPtr = 0; for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { pxv = bm.GetPixel(i, j).ToArgb(); byte alpha = smask[smaskPtr++] = (byte) ((pxv >> 24) & 0xff); /* bugfix by Chris Nokleberg */ if (!shades) { if (alpha != 0 && alpha != 255) { shades = true; } else if (transparency == null) { if (alpha == 0) { transparentPixel = pxv & 0xffffff; transparency = new int[6]; transparency[0] = transparency[1] = (transparentPixel >> 16) & 0xff; transparency[2] = transparency[3] = (transparentPixel >> 8) & 0xff; transparency[4] = transparency[5] = transparentPixel & 0xff; } } else if ((pxv & 0xffffff) != transparentPixel) { shades = true; } } pixelsByte[index++] = (byte) ((pxv >> 16) & 0xff); pixelsByte[index++] = (byte) ((pxv >> 8) & 0xff); pixelsByte[index++] = (byte) (pxv & 0xff); } } if (shades) transparency = null; else smask = null; } Image img = Image.GetInstance(w, h, 3, 8, pixelsByte, transparency); if (smask != null) { Image sm = Image.GetInstance(w, h, 1, 8, smask); sm.MakeMask(); img.ImageMask = sm; } return img; } } /// /// Gets an instance of an Image from a System.Drawing.Image. /// /// the System.Drawing.Image to convert /// /// if different from null the transparency /// pixels are replaced by this color /// /// an object of type ImgRaw public static Image GetInstance(System.Drawing.Image image, Color color) { return Image.GetInstance(image, color, false); } /// /// Gets an instance of an Image. /// /// a filename /// an object of type Gif, Jpeg or Png public static Image GetInstance(string filename) { return GetInstance(Utilities.ToURL(filename)); } /// /// Gets an instance of an Image in raw mode. /// /// the width of the image in pixels /// the height of the image in pixels /// 1,3 or 4 for GrayScale, RGB and CMYK /// bits per component /// the image data /// an object of type ImgRaw public static Image GetInstance(int width, int height, int components, int bpc, byte[] data) { return Image.GetInstance(width, height, components, bpc, data, null); } /** * Reuses an existing image. * @param ref the reference to the image dictionary * @throws BadElementException on error * @return the image */ public static Image GetInstance(PRIndirectReference iref) { PdfDictionary dic = (PdfDictionary)PdfReader.GetPdfObjectRelease(iref); int width = ((PdfNumber)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.WIDTH))).IntValue; int height = ((PdfNumber)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.HEIGHT))).IntValue; Image imask = null; PdfObject obj = dic.Get(PdfName.SMASK); if (obj != null && obj.IsIndirect()) { imask = GetInstance((PRIndirectReference)obj); } else { obj = dic.Get(PdfName.MASK); if (obj != null && obj.IsIndirect()) { PdfObject obj2 = PdfReader.GetPdfObjectRelease(obj); if (obj2 is PdfDictionary) imask = GetInstance((PRIndirectReference)obj); } } Image img = new ImgRaw(width, height, 1, 1, null); img.imageMask = imask; img.directReference = iref; return img; } /// /// Gets an instance of an Image in raw mode. /// /// /// public static Image GetInstance(PdfTemplate template) { return new ImgTemplate(template); } /// /// Gets an instance of an Image in raw mode. /// /// the width of the image in pixels /// the height of the image in pixels /// /// /// /// /// public static Image GetInstance(int width, int height, bool reverseBits, int typeCCITT, int parameters, byte[] data) { return Image.GetInstance(width, height, reverseBits, typeCCITT, parameters, data, null); } /// /// /// /// /// /// /// /// /// /// /// public static Image GetInstance(int width, int height, bool reverseBits, int typeCCITT, int parameters, byte[] data, int[] transparency) { if (transparency != null && transparency.Length != 2) throw new BadElementException("Transparency length must be equal to 2 with CCITT images"); Image img = new ImgCCITT(width, height, reverseBits, typeCCITT, parameters, data); img.transparency = transparency; return img; } /// /// Gets an instance of an Image in raw mode. /// /// the width of the image in pixels /// the height of the image in pixels /// 1,3 or 4 for GrayScale, RGB and CMYK /// bits per component /// the image data /// /// transparency information in the Mask format of the /// image dictionary /// /// an object of type ImgRaw public static Image GetInstance(int width, int height, int components, int bpc, byte[] data, int[] transparency) { if (transparency != null && transparency.Length != components * 2) throw new BadElementException("Transparency length must be equal to (componentes * 2)"); if (components == 1 && bpc == 1) { byte[] g4 = CCITTG4Encoder.Compress(data, width, height); return Image.GetInstance(width, height, false, Element.CCITTG4, Element.CCITT_BLACKIS1, g4, transparency); } Image img = new ImgRaw(width, height, components, bpc, data); img.transparency = transparency; return img; } // methods to set information /// /// Sets the absolute position of the Image. /// /// /// public void SetAbsolutePosition(float absoluteX, float absoluteY) { this.absoluteX = absoluteX; this.absoluteY = absoluteY; } /// /// Scale the image to an absolute width and an absolute height. /// /// the new width /// the new height public void ScaleAbsolute(float newWidth, float newHeight) { plainWidth = newWidth; plainHeight = newHeight; float[] matrix = this.Matrix; scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; WidthPercentage = 0; } /// /// Scale the image to an absolute width. /// /// the new width public void ScaleAbsoluteWidth(float newWidth) { plainWidth = newWidth; float[] matrix = this.Matrix; scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; WidthPercentage = 0; } /// /// Scale the image to an absolute height. /// /// the new height public void ScaleAbsoluteHeight(float newHeight) { plainHeight = newHeight; float[] matrix = Matrix; scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; WidthPercentage = 0; } /// /// Scale the image to a certain percentage. /// /// the scaling percentage public void ScalePercent(float percent) { ScalePercent(percent, percent); } /// /// Scale the width and height of an image to a certain percentage. /// /// the scaling percentage of the width /// the scaling percentage of the height public void ScalePercent(float percentX, float percentY) { plainWidth = (this.Width * percentX) / 100f; plainHeight = (this.Height * percentY) / 100f; float[] matrix = Matrix; scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; WidthPercentage = 0; } /// /// Scales the image so that it fits a certain width and height. /// /// the width to fit /// the height to fit public void ScaleToFit(float fitWidth, float fitHeight) { ScalePercent(100); float percentX = (fitWidth * 100) / this.ScaledWidth; float percentY = (fitHeight * 100) / this.ScaledHeight; ScalePercent(percentX < percentY ? percentX : percentY); WidthPercentage = 0; } /** * Gets the current image rotation in radians. * @return the current image rotation in radians */ public float GetImageRotation() { float rot = (float) ((rotationRadians - initialRotation) % (2.0 * Math.PI)); if (rot < 0) { rot += (float)(2.0 * Math.PI); } return rot; } /// /// Sets the rotation of the image in radians. /// /// rotation in radians public new float Rotation { set { double d=Math.PI; //__IDS__ rotationRadians = (float) ((value + initialRotation) % (2.0 * d)); //__IDS__ if (rotationRadians < 0) { rotationRadians += (float)(2.0 * d); //__IDS__ } float[] matrix = Matrix; scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; } } /// /// Sets the rotation of the image in degrees. /// /// rotation in degrees public float RotationDegrees { set { Rotation = (value / 180 * (float)Math.PI); //__IDS__ } } /// /// Get/set the annotation. /// /// the Annotation public Annotation Annotation { get { return annotation; } set { this.annotation = value; } } // methods to retrieve information /// /// Gets the bpc for the image. /// /// /// this only makes sense for Images of the type RawImage. /// /// a bpc value public int Bpc { get { return bpc; } } /// /// Gets the raw data for the image. /// /// /// this only makes sense for Images of the type RawImage. /// /// the raw data public byte[] RawData { get { return rawData; } } /// /// Get/set the template to be used as an image. /// /// /// this only makes sense for Images of the type ImgTemplate. /// /// the template public PdfTemplate TemplateData { get { return template[0]; } set { this.template[0] = value; } } /// /// Checks if the Images has to be added at an absolute position. /// /// a bool public bool HasAbsolutePosition() { return !float.IsNaN(absoluteY); } /// /// Checks if the Images has to be added at an absolute X position. /// /// a bool public bool HasAbsoluteX() { return !float.IsNaN(absoluteX); } /// /// Returns the absolute X position. /// /// a position public float AbsoluteX { get { return absoluteX; } } /// /// Returns the absolute Y position. /// /// a position public float AbsoluteY { get { return absoluteY; } } /// /// Returns the type. /// /// a type public override int Type { get { return type; } } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public override bool IsNestable() { return true; } /// /// Returns true if the image is a Jpeg-object. /// /// a bool public bool IsJpeg() { return type == Element.JPEG; } /// /// Returns true if the image is a ImgRaw-object. /// /// a bool public bool IsImgRaw() { return type == Element.IMGRAW; } /// /// Returns true if the image is an ImgTemplate-object. /// /// a bool public bool IsImgTemplate() { return type == Element.IMGTEMPLATE; } /// /// Gets the string-representation of the reference to the image. /// /// a string public Uri Url { get { return url; } set { url = value; } } /// /// Get/set the alignment for the image. /// /// a value public int Alignment { get { return alignment; } set { this.alignment = value; } } /// /// Get/set the alternative text for the image. /// /// a string public string Alt { get { return alt; } set { this.alt = value; } } /// /// Gets the scaled width of the image. /// /// a value public float ScaledWidth { get { return scaledWidth; } } /// /// Gets the scaled height of the image. /// /// a value public float ScaledHeight { get { return scaledHeight; } } /// /// Gets the colorspace for the image. /// /// /// this only makes sense for Images of the type Jpeg. /// /// a colorspace value public int Colorspace { get { return colorspace; } } /// /// Returns the transformation matrix of the image. /// /// an array [AX, AY, BX, BY, CX, CY, DX, DY] public float[] Matrix { get { float[] matrix = new float[8]; float cosX = (float)Math.Cos(rotationRadians); float sinX = (float)Math.Sin(rotationRadians); matrix[AX] = plainWidth * cosX; matrix[AY] = plainWidth * sinX; matrix[BX] = (- plainHeight) * sinX; matrix[BY] = plainHeight * cosX; if (rotationRadians < Math.PI / 2f) { matrix[CX] = matrix[BX]; matrix[CY] = 0; matrix[DX] = matrix[AX]; matrix[DY] = matrix[AY] + matrix[BY]; } else if (rotationRadians < Math.PI) { matrix[CX] = matrix[AX] + matrix[BX]; matrix[CY] = matrix[BY]; matrix[DX] = 0; matrix[DY] = matrix[AY]; } else if (rotationRadians < Math.PI * 1.5f) { matrix[CX] = matrix[AX]; matrix[CY] = matrix[AY] + matrix[BY]; matrix[DX] = matrix[BX]; matrix[DY] = 0; } else { matrix[CX] = 0; matrix[CY] = matrix[AY]; matrix[DX] = matrix[AX] + matrix[BX]; matrix[DY] = matrix[BY]; } return matrix; } } /// /// Returns the transparency. /// /// the transparency public int[] Transparency { get { return transparency; } set { transparency = value; } } /// /// Gets the plain width of the image. /// /// a value public float PlainWidth { get { return plainWidth; } } /// /// Gets the plain height of the image. /// /// a value public float PlainHeight { get { return plainHeight; } } /// /// generates new serial id /// static protected long GetSerialId() { lock (serialId) { serialId = (long)serialId + 1L; return (long)serialId; } } /// /// returns serial id for this object /// public long MySerialId { get { return mySerialId; } } /// /// Gets the dots-per-inch in the X direction. Returns 0 if not available. /// /// the dots-per-inch in the X direction public int DpiX { get { return dpiX; } } /// /// Gets the dots-per-inch in the Y direction. Returns 0 if not available. /// /// the dots-per-inch in the Y direction public int DpiY { get { return dpiY; } } /** * Sets the dots per inch value * * @param dpiX * dpi for x coordinates * @param dpiY * dpi for y coordinates */ public void SetDpi(int dpiX, int dpiY) { this.dpiX = dpiX; this.dpiY = dpiY; } /// /// Returns true if this Image has the /// requisites to be a mask. /// /// true if this Image can be a mask public bool IsMaskCandidate() { if (type == Element.IMGRAW) { if (bpc > 0xff) return true; } return colorspace == 1; } /// /// Make this Image a mask. /// public void MakeMask() { if (!IsMaskCandidate()) throw new DocumentException("This image can not be an image mask."); mask = true; } /// /// Get/set the explicit masking. /// /// the explicit masking public Image ImageMask { get { return imageMask; } set { if (this.mask) throw new DocumentException("An image mask cannot contain another image mask."); if (!value.mask) throw new DocumentException("The image mask is not a mask. Did you do MakeMask()?"); imageMask = value; smask = (value.bpc > 1 && value.bpc <= 8); } } /// /// Returns true if this Image is a mask. /// /// true if this Image is a mask public bool IsMask() { return mask; } /// /// Inverts the meaning of the bits of a mask. /// /// true to invert the meaning of the bits of a mask public bool Inverted { set { this.invert = value; } get { return this.invert; } } /// /// Sets the image interpolation. Image interpolation attempts to /// produce a smooth transition between adjacent sample values. /// /// New value of property interpolation. public bool Interpolation { set { this.interpolation = value; } get { return this.interpolation; } } /** Tags this image with an ICC profile. * @param profile the profile */ public ICC_Profile TagICC { get { return profile; } set { this.profile = value; } } /** Checks is the image has an ICC profile. * @return the ICC profile or null */ public bool HasICCProfile() { return (this.profile != null); } public bool Deflated { get { return deflated; } set { deflated = value; } } public PdfDictionary Additional { get { return additional; } set { additional = value; } } public bool Smask { get { return smask; } set { smask = value; } } public float XYRatio { get { return xyRatio; } set { xyRatio = value; } } public float IndentationLeft { get { return indentationLeft; } set { indentationLeft = value; } } public float IndentationRight { get { return indentationRight; } set { indentationRight = value; } } public int OriginalType { get { return originalType; } set { originalType = value; } } public byte[] OriginalData { get { return originalData; } set { originalData = value; } } public float SpacingBefore { get { return spacingBefore; } set { spacingBefore = value; } } public float SpacingAfter { get { return spacingAfter; } set { spacingAfter = value; } } public float WidthPercentage { get { return widthPercentage; } set { widthPercentage = value; } } public IPdfOCG Layer { get { return layer; } set { layer = value; } } private PdfObject SimplifyColorspace(PdfObject obj) { if (obj == null || !obj.IsArray()) return obj; PdfObject first = (PdfObject)(((PdfArray)obj).ArrayList[0]); if (PdfName.CALGRAY.Equals(first)) return PdfName.DEVICEGRAY; else if (PdfName.CALRGB.Equals(first)) return PdfName.DEVICERGB; else return obj; } /** * Replaces CalRGB and CalGray colorspaces with DeviceRGB and DeviceGray. */ public void SimplifyColorspace() { if (additional == null) return; PdfObject value = additional.Get(PdfName.COLORSPACE); if (value == null || !value.IsArray()) return; PdfObject cs = SimplifyColorspace(value); if (cs.IsName()) value = cs; else { PdfObject first = (PdfObject)(((PdfArray)value).ArrayList[0]); if (PdfName.INDEXED.Equals(first)) { ArrayList array = ((PdfArray)value).ArrayList; if (array.Count >= 2 && ((PdfObject)array[1]).IsArray()) { array[1] = SimplifyColorspace((PdfObject)array[1]); } } } additional.Put(PdfName.COLORSPACE, value); } /** * Some image formats, like TIFF may present the images rotated that have * to be compensated. */ public float InitialRotation { get { return initialRotation; } set { float old_rot = rotationRadians - this.initialRotation; this.initialRotation = value; Rotation = old_rot; } } public PdfIndirectReference DirectReference { set { directReference = value; } get { return directReference; } } } }