<?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/"
	>

<channel>
	<title>Kerry D. Wong &#187; GDI+</title>
	<atom:link href="http://www.kerrywong.com/tag/gdi/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kerrywong.com</link>
	<description></description>
	<lastBuildDate>Fri, 03 Sep 2010 00:51:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Understanding &#8220;A generic error occurred in GDI+.&#8221; Error</title>
		<link>http://www.kerrywong.com/2007/11/15/understanding-a-generic-error-occurred-in-gdi-error/</link>
		<comments>http://www.kerrywong.com/2007/11/15/understanding-a-generic-error-occurred-in-gdi-error/#comments</comments>
		<pubDate>Fri, 16 Nov 2007 03:33:04 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[C Sharp (C#)]]></category>
		<category><![CDATA[GDI+]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/2007/11/15/understanding-a-generic-error-occurred-in-gdi-error/</guid>
		<description><![CDATA[When dealing with GDI+ in .Net (e.g. certain&#160;objects in System.Drawing namespace), we would sometimes get the following exception: System.Runtime.InteropServices.ExternalException: &#34;A generic error occurred in GDI+.&#34; Debugging this exception can be extremely frustrating as it can happen under many different circumstances (here and here), and the error message is too generic to provide any useful information. [...]]]></description>
			<content:encoded><![CDATA[<p>When dealing with GDI+ in .Net (e.g. certain&nbsp;objects in System.Drawing namespace), we would sometimes get the following exception:<span id="more-236"></span></p>
<blockquote>
<p><em>System.Runtime.InteropServices.ExternalException: &quot;A generic error occurred in GDI+.&quot;</em></p>
</blockquote>
<p>Debugging this exception can be extremely frustrating as it can happen under many different circumstances (<a href="/2007/11/14/gdi-unable-to-handle-jpeg-compressed-tiff-images/">here</a> and<a href="/2007/10/23/lousy-gdi-error-messages/"> here</a>), and the error message is too generic to provide any useful information.</p>
<p>This exception mostly occurs when trying to write over an image opened by an Image or Bitmap object. For example, the following code snippet will generate this error:</p>
<div style="background: white none repeat scroll 0% 50%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Image</span> img <span style="color: navy;">=</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Image</span><span style="color: navy;">.</span>FromFile(fileName);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue; font-weight: bold;">try</span></div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; img<span style="color: navy;">.</span>Save(fileName); <span style="color: green;">//throws exception!</span></div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue; font-weight: bold;">catch</span> (<span style="color: rgb(43, 145, 175); font-weight: bold;">Exception</span> ex)</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Console</span><span style="color: navy;">.</span>WriteLine(ex<span style="color: navy;">.</span>Message);</div>
<div>
<p>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
</div>
</div>
<p>The method listed above tries to open an image file, process the image (code not shown) and then save the image under the same file name. Unfortunately, due to the way GDI+ handles images, the image file was locked during the whole life time of the img object. And thus an exception was thrown from the underlying Windows API.</p>
<p>Based on <a href="http://support.microsoft.com/?id=814675">Microsoft&#8217;s Knowledgebase article&#8217;s recommendations</a>, we can prevent this exceptions in two ways (see the article for details):</p>
<p><strong>1. Create a non-indexed image:</strong></p>
<div style="background: white none repeat scroll 0% 50%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue; font-weight: bold;">public</span> <span style="color: blue; font-weight: bold;">void</span> Method1()</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Image</span> img <span style="color: navy;">=</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Image</span><span style="color: navy;">.</span>FromFile(fileName);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Bitmap</span> bmp <span style="color: navy;">=</span> img <span style="color: blue; font-weight: bold;">as</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Bitmap</span>;</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Graphics</span> g <span style="color: navy;">=</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Graphics</span><span style="color: navy;">.</span>FromImage(bmp);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Bitmap</span> bmpNew <span style="color: navy;">=</span> <span style="color: blue; font-weight: bold;">new</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Bitmap</span>(bmp);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; g<span style="color: navy;">.</span>DrawImage(bmpNew, <span style="color: blue; font-weight: bold;">new</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Point</span>(<span style="color: teal;">0</span>, <span style="color: teal;">0</span>));</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; g<span style="color: navy;">.</span>Dispose();</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bmp<span style="color: navy;">.</span>Dispose();</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; img<span style="color: navy;">.</span>Dispose();</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">//code to manipulate bmpNew goes here.</span></div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bmpNew<span style="color: navy;">.</span>Save(fileName);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</div>
</div>
<p><strong>2. Create an indexed image:</strong></p>
<div style="background: white none repeat scroll 0% 50%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue; font-weight: bold;">public</span> <span style="color: blue; font-weight: bold;">void</span> Method2()</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Image</span> img <span style="color: navy;">=</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Image</span><span style="color: navy;">.</span>FromFile(fileName);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Bitmap</span> bmp <span style="color: navy;">=</span> img <span style="color: blue; font-weight: bold;">as</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Bitmap</span>;</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">BitmapData</span> bmpData <span style="color: navy;">=</span> bmp<span style="color: navy;">.</span>LockBits(<span style="color: blue; font-weight: bold;">new</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Rectangle</span>(<span style="color: teal;">0</span>, <span style="color: teal;">0</span>, img<span style="color: navy;">.</span>Width, img<span style="color: navy;">.</span>Height), <span style="color: rgb(43, 145, 175); font-weight: bold;">ImageLockMode</span><span style="color: navy;">.</span>ReadWrite, bmp<span style="color: navy;">.</span>PixelFormat);</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue; font-weight: bold;">int</span> byteCount <span style="color: navy;">=</span> bmpData<span style="color: navy;">.</span>Stride <span style="color: navy;">*</span> bmpData<span style="color: navy;">.</span>Height;</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue; font-weight: bold;">byte</span>[] bytes <span style="color: navy;">=</span> <span style="color: blue; font-weight: bold;">new</span> <span style="color: blue; font-weight: bold;">byte</span>[byteCount];</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Marshal</span><span style="color: navy;">.</span>Copy(bmpData<span style="color: navy;">.</span>Scan0,&nbsp; bytes,<span style="color: teal;">0</span>, byteCount);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bmp<span style="color: navy;">.</span>UnlockBits(bmpData);</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Bitmap</span> bmpNew <span style="color: navy;">=</span> <span style="color: blue; font-weight: bold;">new</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Bitmap</span>(bmp<span style="color: navy;">.</span>Width, bmp<span style="color: navy;">.</span>Height);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">BitmapData</span> bmpData1 <span style="color: navy;">=</span> bmpNew<span style="color: navy;">.</span>LockBits(<span style="color: blue; font-weight: bold;">new</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Rectangle</span>(<span style="color: blue; font-weight: bold;">new</span> <span style="color: rgb(43, 145, 175); font-weight: bold;">Point</span>(), bmpNew<span style="color: navy;">.</span>Size), <span style="color: rgb(43, 145, 175); font-weight: bold;">ImageLockMode</span><span style="color: navy;">.</span>ReadWrite, bmp<span style="color: navy;">.</span>PixelFormat);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Marshal</span><span style="color: navy;">.</span>Copy(bytes, <span style="color: teal;">0</span>, bmpData1<span style="color: navy;">.</span>Scan0, bytes<span style="color: navy;">.</span>Length);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bmpNew<span style="color: navy;">.</span>UnlockBits(bmpData1);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bmp<span style="color: navy;">.</span>Dispose();</div>
<div>&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">//code to manipulate bmpNew goes here.</span></div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bmpNew<span style="color: navy;">.</span>Save(fileName);</div>
<div>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</div>
</div>
<p>As can be seen, both methods utilize a secondary image to hold a copy of the original image and makes modifications there. The second image is effectively decoupled from the original one since an explicit copy is made in either method.</p>
<p>The source code of this article can be downloaded <a href="/blog/wp-content/uploads/2007/11/gdipluserror.zip">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2007/11/15/understanding-a-generic-error-occurred-in-gdi-error/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>GDI+ Unable to Handle JPEG Compressed TIFF Images</title>
		<link>http://www.kerrywong.com/2007/11/14/gdi-unable-to-handle-jpeg-compressed-tiff-images/</link>
		<comments>http://www.kerrywong.com/2007/11/14/gdi-unable-to-handle-jpeg-compressed-tiff-images/#comments</comments>
		<pubDate>Thu, 15 Nov 2007 02:55:28 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[GDI+]]></category>
		<category><![CDATA[JPEG]]></category>
		<category><![CDATA[TIFF]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/2007/11/14/gdi-unable-to-handle-jpeg-compressed-tiff-images/</guid>
		<description><![CDATA[A few weeks ago, I wrote about the lousy error message handling in GDI+. Apparently, it is not only just lousy, but incomplete as well. Earlier today at work, I was converting a few TIFF images using a tool I developed a couple of months ago. I encountered &#34;Out of Memory&#34; errors on a few [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, I wrote about the <a href="/2007/10/23/lousy-gdi-error-messages/">lousy error message handling in GDI+</a>. Apparently, it is not only just lousy, but incomplete as well.<span id="more-235"></span></p>
<p>Earlier today at work, I was converting a few TIFF images using a tool I developed a couple of months ago. I encountered &quot;Out of Memory&quot; errors on a few of those images and given my experience before, I had assumed that those images were corrupted (e.g. the header information is invalid). This became somewhat more evident when I tried to open them using the Windows default image viewer (Windows Picture and Fax Viewer), which complained that the image could not be opened.</p>
<p>So at first, I thought that the images were corrupted indeed. But after talking with the engineer who gathered the image, I found out that there was nothing wrong with those images as the same &quot;unreadable&quot; images can be opened by a lot of third party tools. As it turned out, those &quot;unreadable&quot; images are JPEG compressed TIFF images.</p>
<p>After some research, I came to the conclusion that GDI+ in Windows (XP and Server 2003) simply could not handle this type of TIFF file. When opened the returning message is the same as if the file header was not recognized. While I did not find any official article from Microsoft that states such a problem, the following <a href="http://support.microsoft.com/kb/885938">knowledge base article</a> pretty much admitted it.</p>
<p>The workaround mentioned in the knowledge base article however, does not work for me as in my particular situation, the reading of the images need to be autonomous.</p>
<p>As a fast work around due to the time constraint, I used a free command line utility to convert the JPEG compressed TIFF into non-compressed TIFF and sure enough, the formerly unreadable images were read successfully.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2007/11/14/gdi-unable-to-handle-jpeg-compressed-tiff-images/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lousy GDI+ Error Messages</title>
		<link>http://www.kerrywong.com/2007/10/23/lousy-gdi-error-messages/</link>
		<comments>http://www.kerrywong.com/2007/10/23/lousy-gdi-error-messages/#comments</comments>
		<pubDate>Wed, 24 Oct 2007 01:07:19 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[C Sharp (C#)]]></category>
		<category><![CDATA[GDI+]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/2007/10/23/lousy-gdi-error-messages/</guid>
		<description><![CDATA[I have heard many people complaining about how GDI+ handles errors. It seems that many of the GDI+ error messages are either too broad to have any concrete meanings (e.g. &#34;A generic error occurred in GDI+&#34;) or simply just misleading. Trying to open an empty (0 byte) file of any type using&#160; Image.FromFile(&#8230;) function in [...]]]></description>
			<content:encoded><![CDATA[<p>I have heard many people complaining about how GDI+ handles errors. <span id="more-231"></span>It seems that many of the GDI+ error messages are either too broad to have any concrete meanings (e.g. &quot;A generic error occurred in GDI+&quot;) or simply just misleading.</p>
<p>Trying to open an empty (0 byte) file of any type using&nbsp; <span style="color: rgb(43, 145, 175); font-weight: bold;">Image</span><span style="color: maroon; font-weight: bold;">.</span>FromFile(&#8230;) function in .Net&nbsp;  would result in an &quot;Out of memory&quot; exception.</p>
<p>The .Net <span style="color: rgb(43, 145, 175); font-weight: bold;">Image</span><span style="color: maroon; font-weight: bold;">.</span>FromFile() function simply wraps around a GDI+ function GdipLoadImageFromFile and returns whatever error code the underlying function returns. And when an empty file is passed to the FromFile() function, the return code is 3 which translates into &quot;Out of memory&quot;.</p>
<p><!--<br />
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red43\green145\blue175;\red255\green255\blue255;\red128\green0\blue0;\red0\green0\blue0;\red163\green21\blue21;}??\fs20 \cf1 {\b Image}\cf3 {\b .}\cf0 FromFile(\cf5 {\b @"c:\\temp\\1.txt"}\cf0 );}<br />
--></p>
<p>To me, this is really misleading, and I wonder how many developers had been scratching their heads trying to figure out what went wrong with their code when prompted with this error message. I wish Microsoft could have changed it to something more meaningful and in this case something like &quot;Invalid image header&quot; or &quot;Invalid image file format&quot;?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2007/10/23/lousy-gdi-error-messages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
