<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Chris Haas&#039;s Blog</title>
	<atom:link href="http://chrishaas.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://chrishaas.wordpress.com</link>
	<description>Basically a place that Chris can post solutions to problems so he can easily find them later</description>
	<lastBuildDate>Mon, 30 Jan 2012 00:02:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='chrishaas.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Chris Haas&#039;s Blog</title>
		<link>http://chrishaas.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://chrishaas.wordpress.com/osd.xml" title="Chris Haas&#039;s Blog" />
	<atom:link rel='hub' href='http://chrishaas.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Convert iTextSharp Hyperlink from remote webpage to local page number</title>
		<link>http://chrishaas.wordpress.com/2012/01/27/convert-itextsharp-hyperlink-from-remote-webpage-to-local-page-number/</link>
		<comments>http://chrishaas.wordpress.com/2012/01/27/convert-itextsharp-hyperlink-from-remote-webpage-to-local-page-number/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 15:28:57 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[iTextSharp]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=206</guid>
		<description><![CDATA[This post is in response to a comment here. Let&#8217;s say you have a PDF with hyperlinks pointing to URLs like http://www.bing.com and you want to make these instead point to a page internal to the PDF. (Personally I can&#8217;t think of why this would be needed but someone apparently has this need.) We&#8217;ll use [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=206&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is in response to a <a href="/2012/01/06/how-to-recompress-images-in-a-pdf-using-itextsharp/#comment-383">comment here</a>.</p>
<p>Let&#8217;s say you have a PDF with hyperlinks pointing to URLs like <a href="http://www.bing.com" target="_blank">http://www.bing.com</a> and you want to make these instead point to a page internal to the PDF. (Personally I can&#8217;t think of why this would be needed but someone apparently has this need.)</p>
<p>We&#8217;ll use the PDF annotation code that I posted on <a href="http://stackoverflow.com/a/8141831/231316" target="_blank">Stack Overflow here</a> and modify it just a little bit. The code below is written in VB.Net 2010 and targets iTextSharp 5.1.2.0. See the individual code comments for specifics. If you have any questions you can leave a comment here but its probably faster to post your code and problems on <a href="http://stackoverflow.com/" target="_blank">Stack Overflow</a> and just link to this post.</p>
<p>First, we&#8217;ll create some global variables to work with:</p>
<p><pre class="brush: vb;">
    ''//Folder that we are working in
    Private Shared ReadOnly WorkingFolder As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), &quot;Hyperlinked PDFs&quot;)
    ''//Pdf with sample hyperlinks
    Private Shared ReadOnly BaseFile As String = Path.Combine(WorkingFolder, &quot;Base.pdf&quot;)
    ''//Pdf with adjusted hyperlinks
    Private Shared ReadOnly FinalFile As String = Path.Combine(WorkingFolder, &quot;Final.pdf&quot;)
</pre></p>
<p>Next we&#8217;ll create a sample PDF that we can modify URLs with later. Nothing really special here, should be self-explanatory hopefully.</p>
<p><pre class="brush: vb;">
    Private Shared Sub CreateSamplePdf()
        ''//Create our output directory if it does not exist
        Directory.CreateDirectory(WorkingFolder)

        ''//Create our sample PDF
        Using Doc As New iTextSharp.text.Document(PageSize.LETTER)
            Using FS As New FileStream(BaseFile, FileMode.Create, FileAccess.Write, FileShare.Read)
                Using writer = PdfWriter.GetInstance(Doc, FS)
                    Doc.Open()

                    ''//Turn our hyperlinks blue
                    Dim BlueFont As Font = FontFactory.GetFont(&quot;Arial&quot;, 12, iTextSharp.text.Font.NORMAL, iTextSharp.text.BaseColor.BLUE)

                    ''//Create 10 pages with simple labels on them
                    For I = 1 To 10
                        Doc.NewPage()
                        Doc.Add(New Paragraph(String.Format(&quot;Page {0}&quot;, I)))
                        ''//On the first page add some links
                        If I = 1 Then
                           ''//Add an external link
                            Doc.Add(New Paragraph(New Chunk(&quot;Go to website&quot;, BlueFont).SetAction(New PdfAction(&quot;http://www.bing.com/&quot;, False))))

                            ''//Go to a specific hard-coded page number
                            Doc.Add(New Paragraph(New Chunk(&quot;Go to page 5&quot;, BlueFont).SetAction(PdfAction.GotoLocalPage(5, New PdfDestination(0), writer))))
                        End If
                    Next
                    Doc.Close()
                End Using
            End Using
        End Using
    End Sub
</pre></p>
<p>Lastly we&#8217;ll write some code to modify all of the external hyperlinks. The key here is to update the annotation&#8217;s dictionary reference for <code>/S</code>. A remote URL has a <code>/URI</code> (NOTE: the letter <code>I</code> and not <code>L</code>, &#8220;eye&#8221; not &#8220;el&#8221;) and we need to change this to <code>/GOTO</code>. The second trick is that the destination (<code>/D</code>) is an array, of which the first item is an indirect reference to the page that you want to go to and the second item is a fitting option.</p>
<p><pre class="brush: vb;">
    Private Shared Sub ListPdfLinks()

        ''//Setup some variables to be used later
        Dim R As PdfReader
        Dim PageCount As Integer
        Dim PageDictionary As PdfDictionary
        Dim Annots As PdfArray

        ''//Open our reader
        R = New PdfReader(BaseFile)
        ''//Get the page cont
        PageCount = R.NumberOfPages

        ''//Loop through each page
        For I = 1 To PageCount
            ''//Get the current page
            PageDictionary = R.GetPageN(I)

            ''//Get all of the annotations for the current page
            Annots = PageDictionary.GetAsArray(PdfName.ANNOTS)

            ''//Make sure we have something
            If (Annots Is Nothing) OrElse (Annots.Length = 0) Then Continue For

            ''//Loop through each annotation
            For Each A In Annots.ArrayList

                ''//Convert the itext-specific object as a generic PDF object
                Dim AnnotationDictionary = DirectCast(PdfReader.GetPdfObject(A), PdfDictionary)

                ''//Make sure this annotation has a link
                If Not AnnotationDictionary.Get(PdfName.SUBTYPE).Equals(PdfName.LINK) Then Continue For

                ''//Make sure this annotation has an ACTION
                If AnnotationDictionary.Get(PdfName.A) Is Nothing Then Continue For

                ''//Get the ACTION for the current annotation
                Dim AnnotationAction = DirectCast(AnnotationDictionary.Get(PdfName.A), PdfDictionary)

                ''//Test if it is a URI action. NOTE: URI and not URL
                If AnnotationAction.Get(PdfName.S).Equals(PdfName.URI) Then
                    ''//Remove the old action, I don't think this is actually necessary but I do it anyways
                    AnnotationAction.Remove(PdfName.S)
                    ''//Add a new action that is a GOTO action
                    AnnotationAction.Put(PdfName.S, PdfName.GOTO)
                    ''//The destination is an array containing an indirect reference to the page as well as a fitting option
                    Dim NewLocalDestination As New PdfArray()
                    ''//Link it to page 5
                    NewLocalDestination.Add(DirectCast(R.GetPageOrigRef(5), PdfObject))
                    ''//Set it to fit page
                    NewLocalDestination.Add(PdfName.FIT)
                    ''//Add the array to the annotation's destination (/D)
                    AnnotationAction.Put(PdfName.D, NewLocalDestination)
                End If
            Next
        Next

        ''//The above code modified an im-memory representation of a PDF, the code below writes these changes to disk
        Using FS As New FileStream(FinalFile, FileMode.Create, FileAccess.Write, FileShare.None)
            Using Doc As New Document()
                Using writer As New PdfCopy(Doc, FS)
                    Doc.Open()
                    For I = 1 To R.NumberOfPages
                        writer.AddPage(writer.GetImportedPage(R, I))
                    Next
                    Doc.Close()
                End Using
            End Using
        End Using
    End Sub
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/206/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=206&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2012/01/27/convert-itextsharp-hyperlink-from-remote-webpage-to-local-page-number/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
		<item>
		<title>How to recompress images in a PDF using iTextSharp</title>
		<link>http://chrishaas.wordpress.com/2012/01/06/how-to-recompress-images-in-a-pdf-using-itextsharp/</link>
		<comments>http://chrishaas.wordpress.com/2012/01/06/how-to-recompress-images-in-a-pdf-using-itextsharp/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 15:14:11 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[iTextSharp]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=202</guid>
		<description><![CDATA[(I originally posted this on Stack Overflow) iText and iTextSharp have some methods for replacing indirect objects. Specifically there&#8217;s PdfReader.KillIndirect() which does what it says and PdfWriter.AddDirectImageSimple(iTextSharp.text.Image, PRIndirectReference) which you can then use to replace what you killed off. In pseudo C# code you&#8217;d do: Below is a full working C# 2010 WinForms app targeting [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=202&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>(I originally posted this on <a href="http://stackoverflow.com/a/8751517/231316">Stack Overflow</a>)</p>
<p>iText and iTextSharp have some methods for replacing indirect objects. Specifically there&#8217;s <code>PdfReader.KillIndirect()</code> which does what it says and <code>PdfWriter.AddDirectImageSimple(iTextSharp.text.Image, PRIndirectReference)</code> which you can then use to replace what you killed off.</p>
<p>In pseudo C# code you&#8217;d do:</p>
<p><pre class="brush: csharp;">
var oldImage = PdfReader.GetPdfObject();
var newImage = YourImageCompressionFunction(oldImage);
PdfReader.KillIndirect(oldImage);
yourPdfWriter.AddDirectImageSimple(newImage, (PRIndirectReference)oldImage);
</pre></p>
<p>Below is a full working C# 2010 WinForms app targeting iTextSharp 5.1.1.0. It takes an existing JPEG on your desktop called &#8220;LargeImage.jpg&#8221; and creates a new PDF from it. Then it opens the PDF, extracts the image, physically shrinks it to 90% of the original size, applies 85% JPEG compression and writes it back to the PDF. See the comments in the code for more of an explanation. The code needs lots more null/error checking. Also looks for <code>NOTE</code> comments where you&#8217;ll need to expand to handle other situations.</p>
<p><pre class="brush: csharp;">
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            //Our working folder
            string workingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            //Large image to add to sample PDF
            string largeImage = Path.Combine(workingFolder, &quot;LargeImage.jpg&quot;);
            //Name of large PDF to create
            string largePDF = Path.Combine(workingFolder, &quot;Large.pdf&quot;);
            //Name of compressed PDF to create
            string smallPDF = Path.Combine(workingFolder, &quot;Small.pdf&quot;);

            //Create a sample PDF containing our large image, for demo purposes only, nothing special here
            using (FileStream fs = new FileStream(largePDF, FileMode.Create, FileAccess.Write, FileShare.None)) {
                using (Document doc = new Document()) {
                    using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
                        doc.Open();

                        iTextSharp.text.Image importImage = iTextSharp.text.Image.GetInstance(largeImage);
                        doc.SetPageSize(new iTextSharp.text.Rectangle(0, 0, importImage.Width, importImage.Height));
                        doc.SetMargins(0, 0, 0, 0);
                        doc.NewPage();
                        doc.Add(importImage);

                        doc.Close();
                    }
                }
            }

            //Now we're going to open the above PDF and compress things

            //Bind a reader to our large PDF
            PdfReader reader = new PdfReader(largePDF);
            //Create our output PDF
            using (FileStream fs = new FileStream(smallPDF, FileMode.Create, FileAccess.Write, FileShare.None)) {
                //Bind a stamper to the file and our reader
                using (PdfStamper stamper = new PdfStamper(reader, fs)) {
                    //NOTE: This code only deals with page 1, you'd want to loop more for your code
                    //Get page 1
                    PdfDictionary page = reader.GetPageN(1);
                    //Get the xobject structure
                    PdfDictionary resources = (PdfDictionary)PdfReader.GetPdfObject(page.Get(PdfName.RESOURCES));
                    PdfDictionary xobject = (PdfDictionary)PdfReader.GetPdfObject(resources.Get(PdfName.XOBJECT));
                    if (xobject != null) {
                        PdfObject obj;
                        //Loop through each key
                        foreach (PdfName name in xobject.Keys) {
                            obj = xobject.Get(name);
                            if (obj.IsIndirect()) {
                                //Get the current key as a PDF object
                                PdfDictionary imgObject = (PdfDictionary)PdfReader.GetPdfObject(obj);
                                //See if its an image
                                if (imgObject.Get(PdfName.SUBTYPE).Equals(PdfName.IMAGE)) {
                                    //NOTE: There's a bunch of different types of filters, I'm only handing the simplest one here which is basically raw JPG, you'll have to research others
                                    if (imgObject.Get(PdfName.FILTER).Equals(PdfName.DCTDECODE)) {
                                        //Get the raw bytes of the current image
                                        byte[] oldBytes = PdfReader.GetStreamBytesRaw((PRStream)imgObject);
                                        //Will hold bytes of the compressed image later
                                        byte[] newBytes;
                                        //Wrap a stream around our original image
                                        using (MemoryStream sourceMS = new MemoryStream(oldBytes)) {
                                            //Convert the bytes into a .Net image
                                            using (System.Drawing.Image oldImage = Bitmap.FromStream(sourceMS)) {
                                                //Shrink the image to 90% of the original
                                                using (System.Drawing.Image newImage = ShrinkImage(oldImage, 0.9f)) {
                                                    //Convert the image to bytes using JPG at 85%
                                                    newBytes = ConvertImageToBytes(newImage, 85);
                                                }
                                            }
                                        }
                                        //Create a new iTextSharp image from our bytes
                                        iTextSharp.text.Image compressedImage = iTextSharp.text.Image.GetInstance(newBytes);
                                        //Kill off the old image
                                        PdfReader.KillIndirect(obj);
                                        //Add our image in its place
                                        stamper.Writer.AddDirectImageSimple(compressedImage, (PRIndirectReference)obj);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            this.Close();
        }

        //Standard image save code from MSDN, returns a byte array
        private static byte[] ConvertImageToBytes(System.Drawing.Image image, long compressionLevel) {
            if (compressionLevel &lt; 0) {
                compressionLevel = 0;
            } else if (compressionLevel &gt; 100) {
                compressionLevel = 100;
            }
            ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);

            System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
            EncoderParameters myEncoderParameters = new EncoderParameters(1);
            EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, compressionLevel);
            myEncoderParameters.Param[0] = myEncoderParameter;
            using (MemoryStream ms = new MemoryStream()) {
                image.Save(ms, jgpEncoder, myEncoderParameters);
                return ms.ToArray();
            }

        }
        //standard code from MSDN
        private static ImageCodecInfo GetEncoder(ImageFormat format) {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
            foreach (ImageCodecInfo codec in codecs) {
                if (codec.FormatID == format.Guid) {
                    return codec;
                }
            }
            return null;
        }
        //Standard high quality thumbnail generation from http://weblogs.asp.net/gunnarpeipman/archive/2009/04/02/resizing-images-without-loss-of-quality.aspx
        private static System.Drawing.Image ShrinkImage(System.Drawing.Image sourceImage, float scaleFactor) {
            int newWidth = Convert.ToInt32(sourceImage.Width * scaleFactor);
            int newHeight = Convert.ToInt32(sourceImage.Height * scaleFactor);

            var thumbnailBitmap = new Bitmap(newWidth, newHeight);
            using (Graphics g = Graphics.FromImage(thumbnailBitmap)) {
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                System.Drawing.Rectangle imageRectangle = new System.Drawing.Rectangle(0, 0, newWidth, newHeight);
                g.DrawImage(sourceImage, imageRectangle);
            }
            return thumbnailBitmap;
        }
    }
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/202/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=202&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2012/01/06/how-to-recompress-images-in-a-pdf-using-itextsharp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
		<item>
		<title>Speed up iTextSharp&#8217;s PdfReader when reading multiple files or one very large file</title>
		<link>http://chrishaas.wordpress.com/2011/10/13/speed-up-itextsharps-pdfreader-when-reading-multiple-files-or-one-very-large-file/</link>
		<comments>http://chrishaas.wordpress.com/2011/10/13/speed-up-itextsharps-pdfreader-when-reading-multiple-files-or-one-very-large-file/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 22:02:54 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[iTextSharp]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=195</guid>
		<description><![CDATA[Most users of iTextSharp&#8217;s PdfReader are used to using the constructor that takes a single string representing a file path. For small files or only a couple of files this is fine but if you have a document with a large number of pages or just a large number of documents then you might run [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=195&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Most users of iTextSharp&#8217;s PdfReader are used to using the constructor that takes a single string representing a file path. For small files or only a couple of files this is fine but if you have a document with <a href="http://stackoverflow.com/questions/6999296/split-huge-40000-page-pdf-into-single-pages-itextsharp-outofmemoryexception/6999771#6999771" target="_blank">a large number of pages</a> or just a <a href="http://stackoverflow.com/questions/7755951/itextsharp-taking-too-much-time-in-getting-number-of-pages/7759913#7759913" target="_blank">large number of documents</a> then you might run into some performance programs.</p>
<p>Luckily there&#8217;s already a built-in albeit non-obvious solution to the problem : <code>iTextSharp.text.pdf.RandomAccessFileOrArray</code>. When you create a <code>PdfReader</code> using the <code>PdfReader(string)</code> constructor you are actually creating one of these behind the scenes, just not an optimal one. The default one basically sets up a standard <code>FileStream</code> object that reads your file, nothing too special. But there&#8217;s an overload called <code>RandomAccessFileOrArray(string fileName, bool forceRead)</code> that will (generally) give you a giant performance boost if you pass true to the second parameter. When <code>forceRead</code> is <code>true</code> the entire file that you are reading will be read into memory as a byte array. You can understand why the default is <code>false</code>, hopefully. But if you&#8217;ve got a fairly modern machine you should hopefully have enough memory to be able to take advantage of this overload. Obviously test this and <em>stress test</em> this in a product environment. One person loading a 500MB file into memory isn&#8217;t a big deal but 100 people doing it is.</p>
<p>Below is a proof-of-concept WinForms app targeting iTextSharp 5.1.1.0. Just create a blank C# WinForms app (VS2010) and paste this into the source. Modify the variables at the top to your liking for testing. On my machine, the regular <code>PdfReader</code> constructor takes about 22 seconds for 4,000 files and between 1 and 2 seconds using a <code>RandomAccessFileOrArray</code>.</p>
<p><pre class="brush: csharp;">
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //Location to create temporary files. NOTE: This folder will get DELETED when cleaned up!
        private readonly string workingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), &quot;Many Files&quot;);
        //Number of test files to create
        private readonly int fileCount = 4000;
        //Maximum number of pages in each test file
        private readonly int maxNumberOfPages = 20;

        //Will hold our threads
        private Thread tw;
        private Thread tm;

        private void Form1_Load(object sender, EventArgs e)
        {
            //Resize the main form
            this.Width = 350;
            this.Height = 150;

            //Create various buttons
            var btn1 = new Button();
            btn1.Text = &quot;Create sample files&quot;;
            btn1.Click += (a, b) =&gt; BtnClick_CreateSampleFiles();
            btn1.Location = new Point(0, 0);
            btn1.Width = 150;
            this.Controls.Add(btn1);

            var btn2 = new Button();
            btn2.Text = &quot;Count pages old way&quot;;
            btn2.Click += (a, b) =&gt; BtnClick_CountPages_Slow();
            btn2.Location = new Point(0, 25);
            btn2.Width = 150;
            this.Controls.Add(btn2);

            var btn3 = new Button();
            btn3.Text = &quot;Count pages new way&quot;;
            btn3.Click += (a, b) =&gt; BtnClick_CountPages_Fast();
            btn3.Location = new Point(150, 25);
            btn3.Width = 150;
            this.Controls.Add(btn3);

            var btn4 = new Button();
            btn4.Text = &quot;Clean up&quot;;
            btn4.Click += (a, b) =&gt; CleanUp(true);
            btn4.Location = new Point(0, 50);
            btn4.Width = 150;
            this.Controls.Add(btn4);

            var pbFileCreated = new ProgressBar();
            pbFileCreated.Name = &quot;pbFileCreated&quot;;
            pbFileCreated.Location = new Point(0, 75);
            pbFileCreated.Width = 300;
            this.Controls.Add(pbFileCreated);
        }
        /// &lt;summary&gt;
        /// Enable/Disable buttons on the main form
        /// &lt;/summary&gt;
        private void SetFormState(bool enabled){
            //If we are called outside of the main UI thread then we need to invoke into it
            if (this.InvokeRequired){
                this.Invoke(new MethodInvoker(delegate() { SetFormState(enabled); }));
            }else{
                //Disable all buttons
                foreach (Control c in this.Controls){
                    if (c is Button) c.Enabled = enabled;
                }
            }
        }
        #region Button Click Events
        private void BtnClick_CreateSampleFiles(){
            //Disable the UI
            SetFormState(false);
            //Create a thread to do our work
            tw = new Thread(new ThreadStart(this.CreateSampleFiles));
            //Start the thread
            tw.Start();
            //Create a thread to monitor our progress
            tm = new Thread(new ThreadStart(this.Monitor));
            //Start the thread
            tm.Start();
        }
        private void BtnClick_CountPages_Slow(){
            //Disable the UI
            SetFormState(false);
            //Create a thread to do our work
            tw = new Thread(new ThreadStart(this.CountPages_Slow));
            //Start the thread
            tw.Start();
            //Create a thread to monitor our progress
            tm = new Thread(new ThreadStart(this.Monitor));
            tm.Start();
        }
        private void BtnClick_CountPages_Fast(){
            //Disable the UI
            SetFormState(false);
            //Create a thread to do our work
            tw = new Thread(new ThreadStart(this.CountPages_Fast));
            //Start the thread
            tw.Start();
            tm = new Thread(new ThreadStart(this.Monitor));
            //Create a thread to monitor our progress
            tm.Start();
        }
        #endregion
        #region Monitor And ProgressBar
        /// &lt;summary&gt;
        /// Used to monitor the progress of the worker thread so that we know when to re-enable the form's UI
        /// &lt;/summary&gt;
        private void Monitor()
        {
            while (tw != null &amp;&amp; tw.ThreadState == System.Threading.ThreadState.Running)
            {
                Thread.Sleep(250);
            }
            SetFormState(true);
        }
        /// &lt;summary&gt;
        /// Called from various methods on various threads to update the main progress bar
        /// &lt;/summary&gt;
        private void updatePB(int value, int max){
            //Get the progress bar, there should only be only
            var pb = (ProgressBar)this.Controls.Find(&quot;pbFileCreated&quot;, false)[0];
            //See if we are on another thread
            if (pb.InvokeRequired){
                //If so, have the main thread invoke our method with the same paremeters for us
                pb.Invoke(new MethodInvoker(delegate() { updatePB(value, max); }));
            }else{
                //Otherwise update the progress bar's values
                pb.Maximum = fileCount;
                pb.Value = value;
            }
        }
        #endregion

        private void CreateSampleFiles(){
            //Just in case, erase current files
            CleanUp(false);

            //Create our output directory
            Directory.CreateDirectory(workingFolder);

            //Placeholder for our random number of pages to create
            int pageCount;

            //Random number generator
            Random r = new Random();

            //Loop through each file that we need to create
            for (int i = 1; i &lt;= fileCount; i++){
                //Ever 100 files update the main progress bar
                if (i % 100 == 0){
                    updatePB(i, fileCount);
                }

                //Create our temporary PDF
                using (FileStream fs = new FileStream(Path.Combine(workingFolder, String.Format(&quot;{0}.pdf&quot;, i.ToString().PadLeft(8, '0'))), FileMode.Create, FileAccess.Write, FileShare.None)){
                    using (Document doc = new Document(PageSize.LETTER)){
                        using (PdfWriter w = PdfWriter.GetInstance(doc, fs)){
                            doc.Open();

                            //Get a random number of pages to create
                            pageCount = r.Next(1, maxNumberOfPages + 1);
                            for (int j = 1; j &lt;= pageCount; j++){
                                //Add a page
                                doc.NewPage();

                                //Add some content on the page, just to give the page a little &quot;weight&quot;
                                doc.Add(new Paragraph(String.Format(&quot;File {0}, Page {1}&quot;, i, j)));
                            }
                            doc.Close();
                        }
                    }
                }
            }
            //Give an alert to let people know we're done
            MessageBox.Show(String.Format(&quot;Created {0} Files&quot;, fileCount));
        }
        /// &lt;summary&gt;
        /// Clean up the files we created by erasing the entire directory
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;msg&quot;&gt;Whether to show a message alerting when done&lt;/param&gt;
        private void CleanUp(bool msg){
            if (Directory.Exists(workingFolder)){
                Directory.Delete(workingFolder, true);
            }
            if (msg){
                MessageBox.Show(&quot;Test files deleted&quot;);
            }
        }
        /// &lt;summary&gt;
        /// Make sure we have a working folder and the correct number of files in it
        /// &lt;/summary&gt;
        private bool SanityCheck()
        {
            if (!Directory.Exists(workingFolder)){
                MessageBox.Show(&quot;Folder not found, please create first&quot;);
                return false;
            }
            if (Directory.EnumerateFiles(workingFolder, &quot;*.pdf&quot;).Count() != fileCount){
                MessageBox.Show(&quot;Not enough files exist in source folder, please create files before using.&quot;);
                return false;
            }
            return true;
        }
        private void CountPages_Slow(){
            //Make sure we've got files to work with
            if (!SanityCheck()) return;
            //Create a timer
            var st = new Stopwatch();
            //Start it
            st.Start();
            //Get our files
            var files = Directory.EnumerateFiles(workingFolder, &quot;*.pdf&quot;);
            //Total number of pages found
            int totalPageCount = 0;
            //Used to update the progress bar
            int i = 0;
            int localFileCount = files.Count();

            //Loop through each file
            foreach (string f in files){
                //This is a total perf hit but the differences between the two methods is so great it doesn't really matter
                //Every 100 pages update the progress bar
                i++;
                if (i % 100 == 0){
                    updatePB(i, localFileCount);
                }
                //Add the page count to the total
                totalPageCount += new PdfReader(f).NumberOfPages;
            }
            //Stop our timer
            st.Stop();
            MessageBox.Show(String.Format(&quot;Found {0:N0} pages in {1:N0} seconds&quot;, totalPageCount, st.Elapsed.Seconds));
        }
        private void CountPages_Fast(){
            //Make sure we've got files to work with
            if (!SanityCheck()) return;
            //Create a timer
            var st = new Stopwatch();
            //Start it
            st.Start();
            //Get our files
            var files = Directory.EnumerateFiles(workingFolder, &quot;*.pdf&quot;);
            //Total number of pages found
            int totalPageCount = 0;
            //Used to update the progress bar
            int i = 0;
            int localFileCount = files.Count();

            //Loop through each file
            foreach (string f in files){
                //This is a total perf hit but the differences between the two methods is so great it doesn't really matter
                //Every 100 pages update the progress bar
                i++;
                if (i % 100 == 0){
                    updatePB(i, localFileCount);
                }
                //Add the page count to the total
                totalPageCount += new PdfReader(new RandomAccessFileOrArray(f, true), null).NumberOfPages;
            }
            //Stop our timer
            st.Stop();
            MessageBox.Show(String.Format(&quot;Found {0:N0} pages in {1:N0} seconds&quot;, totalPageCount, st.Elapsed.Seconds));
        }
    }
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/195/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=195&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2011/10/13/speed-up-itextsharps-pdfreader-when-reading-multiple-files-or-one-very-large-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
		<item>
		<title>#3 – VB.Net iTextSharp Tutorial – Add a scaled image to a document</title>
		<link>http://chrishaas.wordpress.com/2011/09/03/3-%e2%80%93-vb-net-itextsharp-tutorial-%e2%80%93-add-a-scaled-image-to-a-document/</link>
		<comments>http://chrishaas.wordpress.com/2011/09/03/3-%e2%80%93-vb-net-itextsharp-tutorial-%e2%80%93-add-a-scaled-image-to-a-document/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 14:43:05 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[iTextSharp]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=188</guid>
		<description><![CDATA[This is part of a series of iTextSharp tutorials for VB 2010 Express. See this post for an overview and to answer any basic questions that you may have. This post is a followup to the previous one, this time it scales the image based on the document&#8217;s size<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=188&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is part of a series of iTextSharp tutorials for VB 2010 Express. See <a title="VB.Net tutorial for iTextSharp" href="../2011/09/03/2011/09/03/vb-net-tutorial-for-itextsharp/">this post</a> for an overview and to answer any basic questions that you may have.</p>
<p>This post is a followup to the <a title="#2 – VB.Net iTextSharp Tutorial – Add an image to a document" href="http://chrishaas.wordpress.com/2011/09/03/2-%e2%80%93-vb-net-itextsharp-tutorial-%e2%80%93-add-an-image-to-a-document/">previous one</a>, this time it scales the image based on the document&#8217;s size</p>
<p><pre class="brush: vb;">
Option Explicit On
Option Strict On

Imports System.IO
Imports iTextSharp.text
Imports iTextSharp.text.pdf

Public Class Form1
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        ''//The main folder that we are working in
        Dim WorkingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)

        ''//The file that we are creating
        Dim WorkingFile = Path.Combine(WorkingFolder, &quot;Output.pdf&quot;)

        Dim SampleImage = Path.Combine(WorkingFolder, &quot;IMG_0259.JPG&quot;)

        ''//Create our file with an exclusive writer lock
        Using FS As New FileStream(WorkingFile, FileMode.Create, FileAccess.Write, FileShare.None)
            ''//Create our PDF document
            Using Doc As New Document(PageSize.LETTER)
                ''//Bind our PDF object to the physical file using a PdfWriter
                Using Writer = PdfWriter.GetInstance(Doc, FS)
                    ''//Open our document for writing
                    Doc.Open()

                    ''//Insert a blank page
                    Doc.NewPage()

                    ''//Create a PDF image object from our physical image
                    Dim ThisImage = iTextSharp.text.Image.GetInstance(SampleImage)

                    ''//Use standard ratio resizing algorithms to calculate new image dimensions based on the documents dimensions. This will shrink or grow documents to fit

                    ''//Will hold our new image dimensions
                    Dim NewW, NewH As Single

                    ''//If the image is wider than taller, or the image is just square, set the width statically and calculate the height
                    If ThisImage.Width &gt;= ThisImage.Height Then
                        NewW = Doc.PageSize.Width
                        NewH = (Doc.PageSize.Height * NewW) / Doc.PageSize.Width
                    Else ''//Otherwise do the opposite
                        NewH = Doc.PageSize.Height
                        NewW = (Doc.PageSize.Width * NewH) / Doc.PageSize.Height
                    End If

                    ''//Documents sometimes have margins (and this sample does) so subtract them so that our image in centered in the page
                    NewW -= Doc.RightMargin + Doc.LeftMargin
                    NewH -= Doc.TopMargin + Doc.BottomMargin

                    ''//Scale the image
                    ThisImage.ScaleAbsolute(NewW, NewH)

                    ''//Add the image to the document
                    Doc.Add(ThisImage)

                    ''//Close our document
                    Doc.Close()
                End Using
            End Using
        End Using

        Me.Close()
    End Sub
End Class

</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/188/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/188/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/188/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/188/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/188/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/188/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/188/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/188/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/188/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/188/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/188/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/188/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/188/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/188/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=188&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2011/09/03/3-%e2%80%93-vb-net-itextsharp-tutorial-%e2%80%93-add-a-scaled-image-to-a-document/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
		<item>
		<title>#2 – VB.Net iTextSharp Tutorial – Add an image to a document</title>
		<link>http://chrishaas.wordpress.com/2011/09/03/2-%e2%80%93-vb-net-itextsharp-tutorial-%e2%80%93-add-an-image-to-a-document/</link>
		<comments>http://chrishaas.wordpress.com/2011/09/03/2-%e2%80%93-vb-net-itextsharp-tutorial-%e2%80%93-add-an-image-to-a-document/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 14:17:47 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[iTextSharp]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=186</guid>
		<description><![CDATA[This is part of a series of iTextSharp tutorials for VB 2010 Express. See this post for an overview and to answer any basic questions that you may have.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=186&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is part of a series of iTextSharp tutorials for VB 2010 Express. See <a title="VB.Net tutorial for iTextSharp" href="../2011/09/03/vb-net-tutorial-for-itextsharp/">this post</a> for an overview and to answer any basic questions that you may have.</p>
<p><pre class="brush: vb;">
Option Explicit On
Option Strict On

Imports System.IO
Imports iTextSharp.text
Imports iTextSharp.text.pdf

Public Class Form1
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        ''//The main folder that we are working in
        Dim WorkingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)

        ''//The file that we are creating
        Dim WorkingFile = Path.Combine(WorkingFolder, &quot;Output.pdf&quot;)

        Dim SampleImage = Path.Combine(WorkingFolder, &quot;IMG_0259.JPG&quot;)

        ''//Create our file with an exclusive writer lock
        Using FS As New FileStream(WorkingFile, FileMode.Create, FileAccess.Write, FileShare.None)
            ''//Create our PDF document
            Using Doc As New Document(PageSize.LETTER)
                ''//Bind our PDF object to the physical file using a PdfWriter
                Using Writer = PdfWriter.GetInstance(Doc, FS)
                    ''//Open our document for writing
                    Doc.Open()

                    ''//Insert a blank page
                    Doc.NewPage()

                    ''//Add an image to a document. This does not scale the image or anything so if your image is large it might go off the canvas
                    Doc.Add(iTextSharp.text.Image.GetInstance(SampleImage))

                    ''//Close our document
                    Doc.Close()
                End Using
            End Using
        End Using

        Me.Close()
    End Sub
End Class
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/186/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=186&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2011/09/03/2-%e2%80%93-vb-net-itextsharp-tutorial-%e2%80%93-add-an-image-to-a-document/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
		<item>
		<title>#1 &#8211; VB.Net iTextSharp Tutorial &#8211; Hello World</title>
		<link>http://chrishaas.wordpress.com/2011/09/03/1-vb-net-itextsharp-tutorial-hello-world/</link>
		<comments>http://chrishaas.wordpress.com/2011/09/03/1-vb-net-itextsharp-tutorial-hello-world/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 14:09:49 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[iTextSharp]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=181</guid>
		<description><![CDATA[This is the first in the series of iTextSharp tutorials for VB 2010 Express. See this post for an overview and to answer any basic questions that you may have. This is the starter, the &#8220;hello world&#8221; program done in VB.Net. The comments in the code should hopefully be enough to explain what&#8217;s going on, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=181&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is the first in the series of iTextSharp tutorials for VB 2010 Express. See <a title="VB.Net tutorial for iTextSharp" href="http://chrishaas.wordpress.com/2011/09/03/vb-net-tutorial-for-itextsharp/">this post</a> for an overview and to answer any basic questions that you may have.</p>
<p>This is the starter, the &#8220;hello world&#8221; program done in VB.Net. The comments in the code should hopefully be enough to explain what&#8217;s going on, but after running (and it should run fast, just opens and closes), you should have a PDF on your desktop called &#8220;Output.pdf&#8221;</p>
<p><pre class="brush: vb;">
Option Explicit On
Option Strict On

Imports System.IO
Imports iTextSharp.text
Imports iTextSharp.text.pdf

Public Class Form1
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        ''//The main folder that we are working in
        Dim WorkingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)

        ''//The file that we are creating
        Dim WorkingFile = Path.Combine(WorkingFolder, &quot;Output.pdf&quot;)

        ''//Create our file with an exclusive writer lock
        Using FS As New FileStream(WorkingFile, FileMode.Create, FileAccess.Write, FileShare.None)
            ''//Create our PDF document
            Using Doc As New Document(PageSize.LETTER)
                ''//Bind our PDF object to the physical file using a PdfWriter
                Using Writer = PdfWriter.GetInstance(Doc, FS)
                    ''//Open our document for writing
                    Doc.Open()

                    ''//Insert a blank page
                    Doc.NewPage()

                    ''//Add a simple paragraph with text
                    Doc.Add(New Paragraph(&quot;Hello World&quot;))

                    ''//Close our document
                    Doc.Close()
                End Using
            End Using
        End Using

        Me.Close()
    End Sub
End Class

</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/181/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=181&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2011/09/03/1-vb-net-itextsharp-tutorial-hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
		<item>
		<title>VB.Net tutorial for iTextSharp</title>
		<link>http://chrishaas.wordpress.com/2011/09/03/vb-net-tutorial-for-itextsharp/</link>
		<comments>http://chrishaas.wordpress.com/2011/09/03/vb-net-tutorial-for-itextsharp/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 13:38:27 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[iTextSharp]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=176</guid>
		<description><![CDATA[iTextSharp is a great open source PDF creation and manipulation library and is a port of the original Java version iText. Unfortunately I&#8217;ve found the documentation and samples lacking, especially for VB.Net. The only good collection of tutorials that I&#8217;ve found was written by Mike Brind. While they were a great start for me, they [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=176&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://sourceforge.net/projects/itextsharp/" target="_blank">iTextSharp</a> is a great open source PDF creation and manipulation library and is a port of the original Java version <a href="http://itextpdf.com/" target="_blank">iText</a>. Unfortunately I&#8217;ve found the documentation and samples lacking, especially for VB.Net. The only good collection of tutorials that I&#8217;ve found was written by <a href="http://www.mikesdotnetting.com/Category/20" target="_blank">Mike Brind</a>. While they were a great start for me, they targeted the 4.x series and were written in C#.The tutorials are fairly easy to upgrade and convert to VB.Net but I wanted to have my own collection. So stay tuned to this post for what I hope will be several iTextSharp tutorials.</p>
<p>A couple of things about the tutorials themselves.:</p>
<ul>
<li>All will be written targetting iTextSharp 5.1.1.0 unless otherwise noted.</li>
<li>All will be written using Visual Basic 2010 Express</li>
<li>My comments are written a little weird, they all start with &#8221;//. This is because <a href="http://stackoverflow.com/" target="_blank">StackOverflow&#8217;s</a> (SO) HTML code highlighting system seems to break when using VB comments. So I &#8220;open and close&#8221; and VB comment and then start a C-style comment which seems to work best. One other problem I&#8217;ve had with SO is that apostrophes seem to mess up highlighting in comments, so you&#8217;ll usually see me say &#8220;do not&#8221; instead of &#8220;don&#8217;t&#8221; or &#8220;the objects properties&#8221; instead of &#8220;the object&#8217;s properties&#8221;.</li>
<li>All code samples are complete WinForms apps unless otherwise noted. This means that you should be able to launch VB Express 2010, create a new Windows Forms Application, add a reference to iTextSharp, switch to the code-behind on the form and paste the entire portion of my code on top of the existing code and it will work for you. The only modifications needed might be variables pointing to specific files and those will be called out at the top. If you hunt-and-peck at my code and it doesn&#8217;t work for you, don&#8217;t complain right away. Start with my exact base and modify bits at a time.</li>
<li>The reason I use WinForms apps for samples over Console Apps is because I occassionally need System.Drawing. While you can definately use System.Drawing with a Console App, this route makes copy and pasting of code easier.</li>
<li>If you have a question about a specific tutorial, feel free to post a comment. If a tutorial is about XYZ and you want to know ABC, feel free to also post a comment but don&#8217;t expect an immediate answer. I might eventually get around to it but there&#8217;s no guarantee. Instead, also post your question on StackOverflow. Feel free to cite my tutorial as a reference.</li>
<li>If you find a tutorial helpful I really do enjoy feedback!</li>
<li>All code that I post here is free for you to use as far as I&#8217;m concerned. For licensing of iTextSharp itself please contact <a href="http://itextpdf.com/terms-of-use/index.php" target="_blank">iText</a>. I in no way represent them, work for them or anything. I just like their product.</li>
<li>Some or all examples will execute code directly in Form1_Load. Because of this you&#8217;ll often see a Me.Close() at the end of the code. Because this is all sample code this is just so that I don&#8217;t need to close an empty form every time.</li>
</ul>
<ol>
<li><a title="#1 – VB.Net iTextSharp Tutorial – Hello World" href="http://chrishaas.wordpress.com/2011/09/03/1-vb-net-itextsharp-tutorial-hello-world/">VB.Net iTextSharp Tutorial – Hello World</a></li>
<li><a title="#2 – VB.Net iTextSharp Tutorial – Add an image to a document" href="http://chrishaas.wordpress.com/2011/09/03/2-%e2%80%93-vb-net-itextsharp-tutorial-%e2%80%93-add-an-image-to-a-document/">VB.Net iTextSharp Tutorial – Add an image to a document</a></li>
<li><a title="#3 – VB.Net iTextSharp Tutorial – Add a scaled image to a document" href="http://chrishaas.wordpress.com/2011/09/03/3-%e2%80%93-vb-net-itextsharp-tutorial-%e2%80%93-add-a-scaled-image-to-a-document/">VB.Net iTextSharp Tutorial – Add a scaled image to a document</a></li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/176/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/176/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/176/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/176/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/176/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/176/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/176/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/176/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/176/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/176/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/176/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/176/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/176/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/176/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=176&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2011/09/03/vb-net-tutorial-for-itextsharp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting color information from iTextSharp&#8217;s TextRenderInfo and ITextExtractionStrategy</title>
		<link>http://chrishaas.wordpress.com/2011/07/31/getting-color-information-from-itextsharps-textrenderinfo-and-itextextractionstrategy/</link>
		<comments>http://chrishaas.wordpress.com/2011/07/31/getting-color-information-from-itextsharps-textrenderinfo-and-itextextractionstrategy/#comments</comments>
		<pubDate>Sun, 31 Jul 2011 23:07:01 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=171</guid>
		<description><![CDATA[In order to get color information when using an ITextExtractionStrategy in iTextSharp (5.1.1.0) you need to make the following changes to main iTextSharp code. Once you make these changes you can follow my SO post here for getting font information as well. iTextSharp.text.pdf.parser.GraphicsState.cs iTextSharp.text.pdf.parser.PdfContentStreamProcessor.cs iTextSharp.text.pdf.parser.TextRenderInfo.cs This code is very experimental but so far works pretty [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=171&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In order to get color information when using an ITextExtractionStrategy in iTextSharp (5.1.1.0) you need to make the following changes to main iTextSharp code. Once you make these changes you can follow my SO post <a href="http://stackoverflow.com/questions/6882098/how-can-i-get-text-formatting-with-itextsharp/6884297#6884297" target="_blank">here </a>for getting font information as well.</p>
<p><b>iTextSharp.text.pdf.parser.GraphicsState.cs</b></p>
<p><pre class="brush: csharp;">
//New Fields:
internal BaseColor colorStroke;
internal BaseColor colorNonStroke;

//New Properties:
public BaseColor GetColorStroke() {
    return colorStroke;
}
public BaseColor GetColorNonStroke() {
    return colorNonStroke;
}

//changed constructors:
public GraphicsState(){
    ctm = new Matrix();
    characterSpacing = 0;
    wordSpacing = 0;
    horizontalScaling = 1.0f;
    leading = 0;
    font = null;
    fontSize = 0;
    renderMode = 0;
    rise = 0;
    knockout = true;
    colorStroke = null;
    colorNonStroke = null;
}

/**
* Copy constructor.
* @param source    another GraphicsState object
*/
public GraphicsState(GraphicsState source){
    // note: all of the following are immutable, with the possible exception of font
    // so it is safe to copy them as-is
    ctm = source.ctm;
    characterSpacing = source.characterSpacing;
    wordSpacing = source.wordSpacing;
    horizontalScaling = source.horizontalScaling;
    leading = source.leading;
    font = source.font;
    fontSize = source.fontSize;
    renderMode = source.renderMode;
    rise = source.rise;
    knockout = source.knockout;
    colorStroke = source.colorStroke;
    colorNonStroke = source.colorNonStroke;
}
</pre></p>
<p><b>iTextSharp.text.pdf.parser.PdfContentStreamProcessor.cs</b><br />
<pre class="brush: csharp;">
//append to end of method PopulateOperators()
    RegisterContentOperator(&quot;G&quot;, new SetStrokingGray());
    RegisterContentOperator(&quot;g&quot;, new SetNonStrokingGray());
    RegisterContentOperator(&quot;RG&quot;, new SetStrokingRGB());
    RegisterContentOperator(&quot;rg&quot;, new SetNonStrokingRGB());
    RegisterContentOperator(&quot;K&quot;, new SetStrokingCMYK());
    RegisterContentOperator(&quot;k&quot;, new SetNonStrokingCMYK());
    RegisterContentOperator(&quot;CS&quot;, new SetStrokingGeneral());
    RegisterContentOperator(&quot;cs&quot;, new SetNonStrokingGeneral());
    RegisterContentOperator(&quot;SC&quot;, new SetStrokingGeneral());
    RegisterContentOperator(&quot;sc&quot;, new SetNonStrokingGeneral());
    RegisterContentOperator(&quot;SCN&quot;, new SetStrokingGeneral());
    RegisterContentOperator(&quot;scn&quot;, new SetNonStrokingGeneral());

//add new classes:
public abstract class SetColorBase : IContentOperator {
    public enum ColorStyle { Stroke = 1, NonStroke = 2 };
    public enum ColorSpace { RGB = 1, CMYK = 2, Gray = 3, Other = 4 };
    public abstract BaseColor GetColor(PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands);
    private ColorStyle style;
    private ColorSpace space;
    public SetColorBase(ColorStyle colorStyle, ColorSpace colorSpace) {
        this.style = colorStyle;
        this.space = colorSpace;
    }
    public void Invoke(PdfContentStreamProcessor processor, PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands) {
        BaseColor c = GetColor(oper, operands);
        GraphicsState gs = processor.gsStack.Peek();
        if (this.style == ColorStyle.Stroke) {
            gs.colorStroke = c;
        }
        else if (this.style == ColorStyle.NonStroke) {
            gs.colorNonStroke = c;
        }
    }
}
private class SetStrokingGray : SetColorBase {
    public SetStrokingGray() : base(ColorStyle.Stroke, ColorSpace.Gray) { }
    public override BaseColor GetColor(PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands) {
        PdfNumber g = (PdfNumber)operands[0];
        return new GrayColor(g.FloatValue);
    }
}
private class SetNonStrokingGray : SetColorBase {
    public SetNonStrokingGray() : base(ColorStyle.NonStroke, ColorSpace.Gray) { }
    public override BaseColor GetColor(PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands) {
        PdfNumber g = (PdfNumber)operands[0];
        return new GrayColor(g.FloatValue);
    }
}
private class SetStrokingRGB : SetColorBase {
    public SetStrokingRGB() : base(ColorStyle.Stroke, ColorSpace.RGB) { }
    public override BaseColor GetColor(PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands) {
        PdfNumber r = (PdfNumber)operands[0];
        PdfNumber g = (PdfNumber)operands[1];
        PdfNumber b = (PdfNumber)operands[2];
        return new BaseColor(r.FloatValue, g.FloatValue, b.FloatValue);
    }
}
private class SetNonStrokingRGB : SetColorBase {
    public SetNonStrokingRGB() : base(ColorStyle.NonStroke, ColorSpace.RGB) { }
    public override BaseColor GetColor(PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands) {
        PdfNumber r = (PdfNumber)operands[0];
        PdfNumber g = (PdfNumber)operands[1];
        PdfNumber b = (PdfNumber)operands[2];
        return new BaseColor(r.FloatValue, g.FloatValue, b.FloatValue);
    }
}
private class SetStrokingCMYK : SetColorBase {
    public SetStrokingCMYK() : base(ColorStyle.Stroke, ColorSpace.CMYK) { }
    public override BaseColor GetColor(PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands) {
        PdfNumber c = (PdfNumber)operands[0];
        PdfNumber m = (PdfNumber)operands[1];
        PdfNumber y = (PdfNumber)operands[2];
        PdfNumber k = (PdfNumber)operands[3];
        return new CMYKColor(c.FloatValue, m.FloatValue, y.FloatValue, k.FloatValue);
    }
}
private class SetNonStrokingCMYK : SetColorBase {
    public SetNonStrokingCMYK() : base(ColorStyle.NonStroke, ColorSpace.CMYK) { }
    public override BaseColor GetColor(PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands) {
        PdfNumber c = (PdfNumber)operands[0];
        PdfNumber m = (PdfNumber)operands[1];
        PdfNumber y = (PdfNumber)operands[2];
        PdfNumber k = (PdfNumber)operands[3];
        return new CMYKColor(c.FloatValue, m.FloatValue, y.FloatValue, k.FloatValue);
    }
}
private class SetNonStrokingGeneral : SetColorBase {
    public SetNonStrokingGeneral() : base(ColorStyle.NonStroke, ColorSpace.Other) { }
    public override BaseColor GetColor(PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands) {
        if (operands.Count == 2 &amp;amp;&amp;amp; operands[0].IsNumber() &amp;amp;&amp;amp; ((PdfNumber)operands[0]).IntValue == 0) {
            return new BaseColor(0);
        }
        if (operands.Count == 2 &amp;amp;&amp;amp; operands[0].IsName()) {
            return new BaseColor(0);
        }
        if (operands.Count == 4) {
            PdfNumber r = (PdfNumber)operands[0];
            PdfNumber g = (PdfNumber)operands[1];
            PdfNumber b = (PdfNumber)operands[2];
            return new BaseColor(r.FloatValue, g.FloatValue, b.FloatValue);
        }
        return null;
    }
}
private class SetStrokingGeneral : SetColorBase {
    public SetStrokingGeneral() : base(ColorStyle.Stroke, ColorSpace.Other) { }
    public override BaseColor GetColor(PdfLiteral oper, List&amp;lt;PdfObject&amp;gt; operands) {
        if (operands.Count == 2 &amp;amp;&amp;amp; operands[0].IsNumber() &amp;amp;&amp;amp; ((PdfNumber)operands[0]).IntValue == 0) {
            return new BaseColor(0);
        }
        if (operands.Count == 2 &amp;amp;&amp;amp; operands[0].IsName()) {
            return new BaseColor(0);
        }
        if (operands.Count == 4) {
            PdfNumber r = (PdfNumber)operands[0];
            PdfNumber g = (PdfNumber)operands[1];
            PdfNumber b = (PdfNumber)operands[2];
            return new BaseColor(r.FloatValue, g.FloatValue, b.FloatValue);
        }
    return null;
    }
}
</pre></p>
<p><b>iTextSharp.text.pdf.parser.TextRenderInfo.cs</b><br />
<pre class="brush: csharp;">
//new methods
public BaseColor GetColorStroke() {
    return gs.GetColorStroke();
}
public BaseColor GetColorNonStroke() {
    return gs.GetColorNonStroke();
}
</pre></p>
<p>This code is very experimental but so far works pretty well. Depending on who generates the PDF different things can happen. Word&#8217;s built-in PDF generator seems to take the easier route and just kicks out simple RGB values. Adobe&#8217;s PDF plug-in appears to do the same but in a more complicated way, creating &#8220;named&#8221; color spaces (I think) but I&#8217;m not completely sure how to use them yet.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/171/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/171/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/171/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=171&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2011/07/31/getting-color-information-from-itextsharps-textrenderinfo-and-itextextractionstrategy/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
		<item>
		<title>Don&#8217;t bother with TcpClient.Connected</title>
		<link>http://chrishaas.wordpress.com/2011/02/02/dont-bother-with-tcpclient-connected/</link>
		<comments>http://chrishaas.wordpress.com/2011/02/02/dont-bother-with-tcpclient-connected/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 20:38:54 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.Net]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=164</guid>
		<description><![CDATA[The TcpClient has a Connected property that is very convenient to use but unfortunately it doesn&#8217;t do what you think it should do. A better name for this property would be WasConnected or WasLastOperationSuccessful. The problem is that this property only tells you the status of the last operation. For example, if 30 seconds ago [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=164&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The <code>TcpClient</code> has a <code>Connected</code> property that is very convenient to use but unfortunately it doesn&#8217;t do what you think it should do. A better name for this property would be <code>WasConnected</code> or <code>WasLastOperationSuccessful</code>. The problem is that this property only tells you the status of the last operation. For example, if 30 seconds ago you sent some data this property would be <code>true</code>. If the client that you sent data to calls <code>Close()</code> on their end or their network connection goes down this property will still be <code>true</code>. The latter case you can probably understand but the for the former case you need to understand that there&#8217;s no &#8220;connection agreement&#8221; between the two parties. When one side calls <code>Close()</code> its not going to stay open to send data to the other and potentially wait forever on a slow network connection. Instead, <code>Close()</code> just means &#8220;terminate my side&#8221;. If you want, you can roll your own handshake implementation and have the client send a &#8216;closing connection&#8217; packet but neither side should assume that it will work.</p>
<p>For more information see <a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.connected.aspx" target="_blank">MSDN</a>:</p>
<blockquote><p>Because the Connected property only reflects the state of the connection as of the most recent operation,<strong> you should attempt to send or receive a message to determine the current state</strong>. After the message send fails, this property no longer returns true. Note that this behavior is by design. You cannot reliably test the state of the connection because, in the time between the test and a send/receive, the connection could have been lost. <strong>Your code should assume the socket is connected, and gracefully handle failed transmission</strong>s.</p></blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/164/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/164/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=164&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2011/02/02/dont-bother-with-tcpclient-connected/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
		<item>
		<title>Fake Article: Man who doesn&#8217;t dial 911 loses home to inferno</title>
		<link>http://chrishaas.wordpress.com/2011/02/02/fake-article-man-who-doesnt-dial-911-loses-home-to-inferno/</link>
		<comments>http://chrishaas.wordpress.com/2011/02/02/fake-article-man-who-doesnt-dial-911-loses-home-to-inferno/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 18:15:43 +0000</pubDate>
		<dc:creator>chrishaas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Not Code]]></category>

		<guid isPermaLink="false">http://chrishaas.wordpress.com/?p=161</guid>
		<description><![CDATA[I saw this on Failblog and a bunch of sites also appear to think its legitimate. However digging deeper you&#8217;ll find that Knoxville&#8217;s Newspaper has a sister site called Notsville that posts parody news stories and this is one of them<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=161&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I saw this on Failblog and a bunch of sites also appear to think its legitimate. However digging deeper you&#8217;ll find that Knoxville&#8217;s Newspaper has a sister site called Notsville that posts parody news stories and <a href="http://www.notsville.com/2011/01/man-who-doesnt-dial-911-loses-home-to-inferno.html" target="_blank">this is one of them</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/chrishaas.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/chrishaas.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/chrishaas.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/chrishaas.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/chrishaas.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/chrishaas.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/chrishaas.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/chrishaas.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/chrishaas.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/chrishaas.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/chrishaas.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/chrishaas.wordpress.com/161/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/chrishaas.wordpress.com/161/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/chrishaas.wordpress.com/161/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=chrishaas.wordpress.com&amp;blog=8092262&amp;post=161&amp;subd=chrishaas&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://chrishaas.wordpress.com/2011/02/02/fake-article-man-who-doesnt-dial-911-loses-home-to-inferno/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/860cd8e5ee5064509d0ef587159804eb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">chrishaas</media:title>
		</media:content>
	</item>
	</channel>
</rss>
