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

<channel>
	<title>Web Biz</title>
	<atom:link href="http://blog.brianflove.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.brianflove.com</link>
	<description>ColdFusion and Web Technologies</description>
	<pubDate>Fri, 01 Aug 2008 18:43:15 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>CSS Negation pseudo-class</title>
		<link>http://blog.brianflove.com/articles/2008/08/01/css-negation-pseudo-class/</link>
		<comments>http://blog.brianflove.com/articles/2008/08/01/css-negation-pseudo-class/#comments</comments>
		<pubDate>Fri, 01 Aug 2008 18:43:15 +0000</pubDate>
		<dc:creator>brian</dc:creator>
		
		<category><![CDATA[Web2.0]]></category>

		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://blog.brianflove.com/?p=131</guid>
		<description><![CDATA[Here's a CSS stylesheet tip that I learned today: the negation pseudo-class (meaning it is followed by a colon, like :focus or :visited).  What exactly is it?  Well, its basically the NOT part of an if statement, if you want to think of it that way.  It is extremely useful when you want to apply a style to a class or group of elements, and want to exclude some element(s).]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a CSS stylesheet tip that I learned today: the negation pseudo-class (meaning it is followed by a colon, like :focus or :visited).  What exactly is it?  Well, its basically the NOT part of an if statement, if you want to think of it that way.  It is extremely useful when you want to apply a style to a class or group of elements, and want to exclude some element(s).</p>
<p>I have a form stylesheet that applies styles to all <em>input </em>elements when focused, but I didn&#8217;t want the styles to apply to <em>input </em>elements whose type equals &#8217;submit&#8217; or &#8216;button&#8217; when focused.  So lets see how it works.</p>
<p>First, I define the style for all input elements:</p>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('1311');">[<span id="1311_symbol">-</span>]</a></span><span class="codebox_left"><span id="l131code1"><a href="javascript:;" onclick="javascript:showCodeTxt('131code1'); return false;">View Code</a> CSS</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="1311"><td width="1%" class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="131code1"><pre class="css">form input, form textarea <span style="color: #66cc66;">&#123;</span>
  width<span style="color: #3333ff;">:<span style="color: #933;">200px</span></span><span style="color: #66cc66;">;</span>
  padding<span style="color: #3333ff;">:<span style="color: #933;">1px</span></span><span style="color: #66cc66;">;</span>
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>To remove these styles (width and padding properties), I can override them later in my stylesheet using:</p>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('1312');">[<span id="1312_symbol">-</span>]</a></span><span class="codebox_left"><span id="l131code2"><a href="javascript:;" onclick="javascript:showCodeTxt('131code2'); return false;">View Code</a> CSS</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="1312"><td width="1%" class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="131code2"><pre class="css">form input<span style="color: #66cc66;">&#91;</span>type=<span style="color: #ff0000;">'submit'</span><span style="color: #66cc66;">&#93;</span>, form input<span style="color: #66cc66;">&#91;</span>type=<span style="color: #ff0000;">'button'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#123;</span>
  padding<span style="color: #3333ff;">:<span style="color: #933;">0px</span></span><span style="color: #66cc66;">;</span>
  width<span style="color: #3333ff;">:auto</span><span style="color: #66cc66;">;</span>
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>This worked great.  I then continued to apply styles to input elements when focused:</p>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('1313');">[<span id="1313_symbol">-</span>]</a></span><span class="codebox_left"><span id="l131code3"><a href="javascript:;" onclick="javascript:showCodeTxt('131code3'); return false;">View Code</a> CSS</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="1313"><td width="1%" class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="131code3"><pre class="css">form input<span style="color: #3333ff;">:focus</span>, form textarea<span style="color: #3333ff;">:focus</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">color</span><span style="color: #66cc66;">:</span><span style="color: #cc00cc;">#<span style="color: #933;">000</span></span><span style="color: #66cc66;">;</span>
  <span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #66cc66;">:</span> <span style="color: #cc00cc;">#EFEFEF</span><span style="color: #66cc66;">;</span>
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>But then, the problem came up with the color property - how do I negate it for the buttons?  I didn&#8217;t want to have to specify a color, becuase otherwise it removes the browser/OS styling to the button.  So, I did some research and realized there is negation pseudo-class for CSS (level 3).  Here is how I modified the above style declaration to not include buttons within my form:</p>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('1314');">[<span id="1314_symbol">-</span>]</a></span><span class="codebox_left"><span id="l131code4"><a href="javascript:;" onclick="javascript:showCodeTxt('131code4'); return false;">View Code</a> CSS</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="1314"><td width="1%" class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="131code4"><pre class="css">form input<span style="color: #3333ff;">:focus</span>, form textarea<span style="color: #3333ff;">:focus</span>, form input<span style="color: #3333ff;">:not</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>type=<span style="color: #ff0000;">'submit'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>, form input<span style="color: #3333ff;">:not</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#91;</span>type=<span style="color: #ff0000;">'button'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">color</span><span style="color: #66cc66;">:</span><span style="color: #cc00cc;">#<span style="color: #933;">000</span></span><span style="color: #66cc66;">;</span>
  <span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #66cc66;">:</span> <span style="color: #cc00cc;">#EFEFEF</span><span style="color: #66cc66;">;</span>
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>Now, the styles are only applied to input and textarea elements whose type attibute does NOT equal &#8217;submit&#8217; or &#8216;button&#8217; - pretty cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianflove.com/articles/2008/08/01/css-negation-pseudo-class/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Switching jobs and more [OT]</title>
		<link>http://blog.brianflove.com/articles/2008/07/15/switching-jobs-and-more-ot/</link>
		<comments>http://blog.brianflove.com/articles/2008/07/15/switching-jobs-and-more-ot/#comments</comments>
		<pubDate>Tue, 15 Jul 2008 17:04:59 +0000</pubDate>
		<dc:creator>brian</dc:creator>
		
		<category><![CDATA[ColdFusion]]></category>

		<category><![CDATA[CFUG]]></category>

		<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://blog.brianflove.com/?p=130</guid>
		<description><![CDATA[This announcement is pretty late, as I started the new job the second week in June, but none the less: I recently left my position as the Web Integration Specialist on the Hamilton College Web Services team to join the Webucator team as the Development Manager.  I also have been asked to serve as the co-manager for the ColdFusion User Group of Central New York!]]></description>
			<content:encoded><![CDATA[<p style="text-align: right;"><em>Warning: Off Topic</em></p>
<p>This announcement is pretty late, as I started the new job the second week in June, but none the less:  I recently left my position as the Web Integration Specialist on the <a href="http://www.hamilton.edu/college/its/teams_and_members/teams_and_members_home.html#team_seven">Hamilton College Web Services</a> team to join the <a href="http://www.webucator.com">Webucator</a> team as the Development Manager.</p>
<p>The move has been extremely rewarding, exciting, and _busy_.  I really enjoyed working at Hamilton College, and my colleagues there are irreplacable, but decided to venture out of the world of academics and into the private sector.  Webucator specializes in customized training that is delivered Onsite, Instructor led online, and self-paced.  If you are looking for training, be sure to <a href="http://www.webucator.com/contact.cfm">contact us</a> - shameless plug, I know =)</p>
<p>The second major announcement is that I will be serving alongside <a href="http://www.petefreitag.com/">Pete Freitag</a> as the co-manager for the <a href="http://cfugcny.org/">ColdFusion User Group of Central New York</a>.  It was very cool of Pete to ask me to help out, and I look forward to working with Pete in the coming months and years as well as the future of the CNY CFUG.  I hope to be able to expand the membership size and activeness of the group, bring in some more guest presenters, increase sponsorship, and promote Adobe products and CF in the area.  If you haven&#8217;t attended a meeting before, we would love to have you join us on the 2nd Tuesday of the month.</p>
<p>As the change in my career and life begins to settle back down I look forward to making further enhancements and fixes to my CF Docs on AIR application, and some of the other side-projects I have started.  I also look forward to posting some more blog posts in the near future as well - I have several things ready to go and hope to post these soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianflove.com/articles/2008/07/15/switching-jobs-and-more-ot/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Google Gears Presentation</title>
		<link>http://blog.brianflove.com/articles/2008/07/14/google-gears-presentation/</link>
		<comments>http://blog.brianflove.com/articles/2008/07/14/google-gears-presentation/#comments</comments>
		<pubDate>Tue, 15 Jul 2008 00:45:47 +0000</pubDate>
		<dc:creator>brian</dc:creator>
		
		<category><![CDATA[Google]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[Gears]]></category>

		<guid isPermaLink="false">http://blog.brianflove.com/?p=124</guid>
		<description><![CDATA[I presented on Gears, which is a set a tools available to Web Developers to build more compelling  web application. So, its all about offline, right? Well -- kinda.  Gears exposes new modules and capabilities to the browser that provide general purpose building blocks for web applications to unlock the capabilities of the local machine in a safe manner.]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.brianflove.com/wp-content/uploads/2008/07/gears.pdf"><img class="alignright size-full wp-image-126" title="Gears" src="http://blog.brianflove.com/wp-content/uploads/2008/07/gears_th.jpg" alt="Google Gears" width="200" height="150" /></a>I presented on <a title="Gears" href="http://code.google.com/apis/gears/">Gears</a>, which is a set a tools available to Web Developers to build more compelling application through expanded capabilities in the browser.  I gave this presentation at the <a href="http://cfugcny.org/">Central New York ColdFusion User Group</a> meeting in July to provide a basic introduction to the main modules of Gears and to highlight some of the potential it provides ColdFusion developers, and all web developers.</p>
<h3>You may be asking yourself: <em>Gears, that&#8217;s all about offline, right?</em></h3>
<p>Well &#8212; kinda.</p>
<p>Gears exposes new modules and capabilities that provide general purpose building blocks for web applications to unlock the capabilities of the local machine in a safe manner.<br />
<strong></strong></p>
<h3>Here&#8217;s some code</h3>
<p>For the presentation, I put together a quick sample that shows how the offline Database module works, which stores information into a local Sqlite database on the client.  The sample is pretty simple and easy, which goes to show how accessible Gears is to every web developer out there.</p>
<p>To start off with, a simple init() function is called on window load:</p>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('1245');">[<span id="1245_symbol">-</span>]</a></span><span class="codebox_left"><span id="l124code5"><a href="javascript:;" onclick="javascript:showCodeTxt('124code5'); return false;">View Code</a> JAVASCRIPT</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="1245"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="124code5"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> init<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
  db = google.<span style="color: #006600;">gears</span>.<span style="color: #006600;">factory</span>.<span style="color: #006600;">create</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'beta.database'</span><span style="color: #66cc66;">&#41;</span>;
  db.<span style="color: #000066;">open</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'database-test'</span><span style="color: #66cc66;">&#41;</span>;
  db.<span style="color: #006600;">execute</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'create table if not exists Users'</span> + <span style="color: #3366CC;">' (id INTEGER PRIMARY KEY AUTOINCREMENT, firstname varchar(100), lastname varchar(100), Description text, Timestamp int)'</span><span style="color: #66cc66;">&#41;</span>;
  list<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>The init() function creates a table Users, and specifies the table schema, then calls the init() function, which populates a div with a simple table:</p>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('1246');">[<span id="1246_symbol">-</span>]</a></span><span class="codebox_left"><span id="l124code6"><a href="javascript:;" onclick="javascript:showCodeTxt('124code6'); return false;">View Code</a> JAVASCRIPT</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="1246"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="124code6"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> list<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
  $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'tablecontainer'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">innerHTML</span> = <span style="color: #3366CC;">''</span>;
  <span style="color: #003366; font-weight: bold;">var</span> html = <span style="color: #3366CC;">'&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;First name&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Last name&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Actions&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;'</span>
  rs = db.<span style="color: #006600;">execute</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'select * from Users order by Timestamp desc'</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #66cc66;">&#40;</span>rs.<span style="color: #006600;">isValidRow</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    html += <span style="color: #3366CC;">'&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;'</span>+rs.<span style="color: #006600;">fieldByName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'firstname'</span><span style="color: #66cc66;">&#41;</span>+<span style="color: #3366CC;">'&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;'</span>+rs.<span style="color: #006600;">fieldByName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'lastname'</span><span style="color: #66cc66;">&#41;</span>+<span style="color: #3366CC;">'&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;'</span>+rs.<span style="color: #006600;">fieldByName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'Description'</span><span style="color: #66cc66;">&#41;</span>+<span style="color: #3366CC;">'&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;a href=&quot;javascript:del('</span>+rs.<span style="color: #006600;">fieldByName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #66cc66;">&#41;</span>+<span style="color: #3366CC;">');&quot;&amp;gt;Delete&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;'</span>;
    rs.<span style="color: #006600;">next</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #66cc66;">&#125;</span>
  rs.<span style="color: #000066;">close</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
  html += <span style="color: #3366CC;">'&amp;lt;/table&amp;gt;'</span>
  $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'tablecontainer'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">innerHTML</span> = html;
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>The list function executes a DB call to select the data from the local Sqlite table we created in the init() function. Then using the record set object that is returned from the execute() method, we call it&#8217;s isValidRow() method.  This lets us know if the current record is indeed a record, and we keep going to the next record until it returns false.  Lastly, we close the record set object, and write out the html to browser.</p>
<p>For inserting a record into the table, its pretty easy (notice, I am also using the Prototype.js library here, which seems to work just fine with Gears):</p>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('1247');">[<span id="1247_symbol">-</span>]</a></span><span class="codebox_left"><span id="l124code7"><a href="javascript:;" onclick="javascript:showCodeTxt('124code7'); return false;">View Code</a> JAVASCRIPT</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="1247"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="124code7"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> create<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
  db.<span style="color: #006600;">execute</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'insert into Users (firstname, lastname, Description, Timestamp) values (?, ?, ?, ?)'</span>, <span style="color: #66cc66;">&#91;</span>$F<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'firstname'</span><span style="color: #66cc66;">&#41;</span>, $F<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'lastname'</span><span style="color: #66cc66;">&#41;</span>, $F<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'Description'</span><span style="color: #66cc66;">&#41;</span>, <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">getTime</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;
  lastid = db.<span style="color: #006600;">lastInsertRowId</span>;
  list<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>The create() function shows how you use bind parameters (?), which you should use whenever the user&#8217;s input is being executed against the SQL database to prevent SQL injection attacks.  This function also shows how you can easily obtain the last row id, which is helpful when using a auto_increment primary key.</p>
<p><strong></strong></p>
<h3>Creating a desktop shortcut</h3>
<p>The second quick demo during the presentation showed how easy it is to create a custom desktop shortcut using Gears, here&#8217;s the code:</p>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('1248');">[<span id="1248_symbol">-</span>]</a></span><span class="codebox_left"><span id="l124code8"><a href="javascript:;" onclick="javascript:showCodeTxt('124code8'); return false;">View Code</a> JAVASCRIPT</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="1248"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="124code8"><pre class="javascript"><span style="color: #003366; font-weight: bold;">function</span> createShortcut<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> desktop = google.<span style="color: #006600;">gears</span>.<span style="color: #006600;">factory</span>.<span style="color: #006600;">create</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'beta.desktop'</span><span style="color: #66cc66;">&#41;</span>;
  desktop.<span style="color: #006600;">createShortcut</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;CFUG Gears Demo&quot;</span>,
    <span style="color: #3366CC;">&quot;http://brianflove.dev/CFUGCNY/Gears/&quot;</span>,
    <span style="color: #66cc66;">&#123;</span><span style="color: #3366CC;">&quot;128x128&quot;</span>: <span style="color: #3366CC;">&quot;http://brianflove.dev/CFUGCNY/Gears/icon_128.png&quot;</span>,
     <span style="color: #3366CC;">&quot;48x48&quot;</span>: <span style="color: #3366CC;">&quot;http://brianflove.dev/CFUGCNY/Gears/icon_48.png&quot;</span>,
     <span style="color: #3366CC;">&quot;32x32&quot;</span>: <span style="color: #3366CC;">&quot;http://brianflove.dev/CFUGCNY/Gears/icon_32.png&quot;</span>,
     <span style="color: #3366CC;">&quot;16x16&quot;</span>: <span style="color: #3366CC;">&quot;http://brianflove.dev/CFUGCNY/Gears/icon_16.png&quot;</span><span style="color: #66cc66;">&#125;</span>,
    <span style="color: #3366CC;">&quot;CFUG - Gears Demo Application http://brianflove.dev/CFUGCNY/Gears/&quot;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p><strong></strong></p>
<h3>Want to know more?</h3>
<ul>
<li><a href="http://blog.brianflove.com/wp-content/uploads/2008/07/gears.pdf">Download the Presentation [PDF]<br />
</a></li>
<li><a href="http://brianflove.com/public/Gears">View the sample</a></li>
<li><a href="http://code.google.com/apis/gears/">Visit the Gears API page</a></li>
<li><a href="http://sites.google.com/site/io/">Watch the presentation from the Google I/O Conference</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianflove.com/articles/2008/07/14/google-gears-presentation/feed/</wfw:commentRss>
		</item>
		<item>
		<title>AJAX Libraries API from Google</title>
		<link>http://blog.brianflove.com/articles/2008/06/02/ajax-libraries-api-from-google/</link>
		<comments>http://blog.brianflove.com/articles/2008/06/02/ajax-libraries-api-from-google/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 14:09:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Google]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[Web2.0]]></category>

		<category><![CDATA[Prototype]]></category>

		<category><![CDATA[scriptaculous]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[As you might have heard, Google has joined the ranks of AOL and others with their newly released AJAX Libraries API.&#160; What does this mean for you as a developer?&#160; Well, Google will now provide hosting of various JS libraries.&#160; So, you get the power of Google to serve the file to your clients, so you can depend on their reliability and incredible speed.]]></description>
			<content:encoded><![CDATA[<p>As you might have heard, Google has joined the ranks of AOL and others with their newly released AJAX Libraries API.  What does this mean for you as a developer?  Well, Google will now provide hosting of various JS libraries.  So, you get the power of Google to serve the file to your clients, so you can depend on their reliability and incredible speed.</p>
<p>This was just one of the several major announcements that were released at last weeks Google I/O developer conference that I was able to attend.  Here is what they say:</p>
<blockquote><p>The AJAX Libraries API is a content distribution network and loading architecture for the most popular open source JavaScript libraries. By using the <a href="/apis/ajax/documentation/">Google AJAX API Loader&#8217;s</a> <code>google.load()</code> method, your application has high speed, globaly available access to a growing list of the most popular JavaScript open source libraries including:</p>
<ul>
<li><a href="documentation/index.html#jquery">jQuery</a></li>
<li><a href="documentation/index.html#prototype">prototype</a></li>
<li><a href="documentation/index.html#script_aculo_us">script.aculo.us</a></li>
<li><a href="documentation/index.html#mootools">MooTools</a></li>
<li><a href="documentation/index.html#dojo">dojo</a></li>
</ul>
<p>Google works directly with the key stake holders for each library effort and accept the latest stable versions as they are released. Once we host a release of a given library, we are committed to hosting that release indefinitely.</p></blockquote>
<p>Read more: <a href="http://code.google.com/apis/ajaxlibs/">http://code.google.com/apis/ajaxlibs/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianflove.com/articles/2008/06/02/ajax-libraries-api-from-google/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Jpeg resolution via EXIF Metadata</title>
		<link>http://blog.brianflove.com/articles/2008/04/17/jpeg-resolution-via-exif-metadata/</link>
		<comments>http://blog.brianflove.com/articles/2008/04/17/jpeg-resolution-via-exif-metadata/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 10:55:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[ColdFusion]]></category>

		<category><![CDATA[ColdFusion 8]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Exif]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I recently worked on a project that required obtaining the resolution of photograph.&#160; The approach I used was to limit the photographs to Jpeg format images only, which I could then use the new imageGetEXIFMetada() function in ColdFusion 8 to obtain the X-Resolution and Y-Resolution tags.&#160; Here is a quick summary of some of my findings and problems.]]></description>
			<content:encoded><![CDATA[<p>I recently worked on a project that required obtaining the resolution of photograph.  The approach I used was to limit the photographs to Jpeg format images only, which I could then use the new <em>imageGetEXIFMetada()</em> function in ColdFusion 8 to obtain the X-Resolution and Y-Resolution tags.  Here is a quick summary of some of my findings and problems.</p>
<p>First off, lets make sure we&#8217;re all on the same page with EXIF - because I had no idea what the EXIF metadata was when I first started the project.  So, lets have our friend wikipedia explain it to us:</p>
<blockquote><p>Exchangeable image file format (Exif) is a specification for the image file format used by digital cameras. The specification uses the existing JPEG, TIFF Rev. 6.0, and RIFF WAV file formats, with the addition of specific metadata tags. It is not supported in JPEG 2000, PNG, or GIF.</p></blockquote>
<p>Basically, the Jpeg file format allows for a variety of custom metadata segments to be stored in the Jpeg image file including the Exif metadata and the IPTC format (usually stores information about the author).  So, if you have a digital camera, your Jpeg images will contain information about the camera and the photograph, including the resolution of the image.</p>
<h3>EXIF - a standard?</h3>
<p>However, from what I have experienced, this &#8220;standard&#8221; isn&#8217;t really that consistent, and depends largely upon the implementation chosen by camera manufacturers and photo editing software makers.  Also, keep in mind that not all Jpegs will contain EXIF or IPTC metadata or may only contain some information.</p>
<h3>IFD - wtf?</h3>
<p>So, after performing some tests on several images using CF 8.0.1 and the <em>imageGetExifMetadat()</em> function, I thought perhaps there was more there than what was being returned by CF.</p>
<p>The Exif format uses several Image File Directories (IFD) to store information about the main image, a link to the sub IFD (if applicable), and a link to the location of IFD1, which is the IFD for the thumbnail image.  In the end, this means that there are potentially 3 directories of metadata: 0 contains information about the main image, SubIFD contains information about the digital camera (such as shutter speed, focal length, etc&#8230;), and 1 contains information about the thumbnail and the thumbnail itself.</p>
<p>The first thing I did was download the Firefox plugin called Exif Viewer.  This tool allows you to view all of the EXIF and IPTC metadata embedded into a local or remote Jpeg file.  First thing I noticed with this is that it appears that CF (which in turn uses the metadata-extractor Java library) is pulling the resolution from the thumbnail properties.</p>
<p><strong>Note:</strong> the reason why my thumbnail and main image have different resolutions is because I used PS to adjust the image&#8217;s resolution and size.  I think it is safe to assume that many people will crop/alter photos prior to uploading them into a web application.  However, for those that do not, the resolution of both the main image and the thumbnail should be the same - so you may not experience this issue when that is the case.</p>
<h3>Testing it out</h3>
<p>Using a sample image, lets look at the difference between the structure returned by CF (remember, its just a Java metadata-extractor library).  Here is what is returned from the Exif Viewer Firefox plugin:</p>
<blockquote><p>Exif IFD0<br />
* Camera Make = Apple<br />
* Camera Model = iPhone<br />
* Picture Orientation = normal (1)<br />
* X-Resolution = 3000000/10000 = 300<br />
* Y-Resolution = 3000000/10000 = 300<br />
* X/Y-Resolution Unit = inch (2)<br />
* Software/Firmware Version = Adobe Photoshop CS3 Windows<br />
* Last Modified Date/Time = 2008:04:15 09:15:42</p>
<p>Exif Sub IFD<br />
* Lens F-Number/F-Stop = 14/5 = F2.8<br />
* Original Date/Time = 2007:11:08 12:26:54<br />
* Digitization Date/Time = 2007:11:08 12:26:54<br />
* Colour Space = sRGB (1)<br />
* Image Width = 1200 pixels<br />
* Image Height = 900 pixels<br />
* Unknown tag: Tagnum = 0xa500 ===&gt; data = 11/5</p>
<p>Exif IFD1<br />
* Compression = JPEG compression (6)<br />
* X-Resolution = 72/1 = 72<br />
* Y-Resolution = 72/1 = 72<br />
* X/Y-Resolution Unit = inch (2)</p></blockquote>
<p>And, here is what is returned from ColdFusion:</p>
<div>
<div><img src="/UserFiles/Image/posts/EXIFMetadata1.jpg" border="0" alt="" width="309" height="411" /></div>
<div>Wait a second?  CF is telling me that the image has a resolution of 72 DPI, when Exif viewer is telling me that in fact the resolution of the image is 300 dpi and the resolution of the embedded thumbnail is 72 dpi.  My inclinations tell me that CF is pulling the wrong information, but we know that CF is just putting a nice wrapper on the metadata-extractor Java lib.  So, my thinking is that either CF&#8217;s implementation is flawed, the Java lib is flawed, or this whole concept of Exif metadata is flawed (which some have argued).</p>
<h3>Using Metadata-extractor</h3>
<p>Based on my previous test (and other tests that I performed), I wanted to determine if I could pull the resolution from the correct IFD using the metadata-extractor Java lib.  For some reason I thought I could do better than the engineers at Adobe (hah!  riggghhhttt) who are Java programmers (and I haven&#8217;t touched much Java code since college).  Well, just to prove myself wrong, I tried (and didn&#8217;t get anywhere, if its worth noting) and here is what I came up with.</p>
<p>First, there are several approaches that can be used to get at the Exif metadata using this library.  I decided to try 3 different methods:</p>
<ol>
<li>ExifReader class implementation,</li>
<li>JpegSegmentReader class implementation, and</li>
<li>JpegMetadataReader class implementation.</li>
</ol>
<p>For each implementation I used some common variables that I param out at the beginning:</p>
<blockquote>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('1209');">[<span id="1209_symbol">-</span>]</a></span><span class="codebox_left"><span id="l120code9"><a href="javascript:;" onclick="javascript:showCodeTxt('120code9'); return false;">View Code</a> COLDFUSION</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="1209"><td width="1%" class="line_numbers"><pre>1
</pre></td><td class="code" id="120code9"><pre>&nbsp;</pre></td></tr></table></div>

</blockquote>
<p>The following is code to read the Exif meta data and loop over each directory and output all the tag information for each implementation above:</p>
<h3>ExifReader implementation</h3>
<p><strong>Code:</strong></p>
<blockquote>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('12010');">[<span id="12010_symbol">-</span>]</a></span><span class="codebox_left"><span id="l120code10"><a href="javascript:;" onclick="javascript:showCodeTxt('120code10'); return false;">View Code</a> COLDFUSION</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="12010"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="120code10"><pre>extractor = createObject(&quot;java&quot;,&quot;com.drew.metadata.exif.ExifReader&quot;).init(createObject(&quot;java&quot;,&quot;java.io.File&quot;).init(expandPath('./')&amp;amp;photoname));
md = extractor.extract();
directories = md.getDirectoryIterator();
while (directories.hasNext()){
    directory = directories.next();
    tags = directory.getTagIterator();
    while (tags.hasNext()) {
         tag = tags.next();
         WriteOutput(tag.getTagName()&amp;amp;': '&amp;amp;tag.getDescription()&amp;amp;'');
    }
}</pre></td></tr></table></div>

</blockquote>
<p><strong>Output:</strong><br />
Make: Apple<br />
Model: iPhone<br />
Orientation: Top, left side (Horizontal / normal)<br />
X Resolution: 72 dots per inch<br />
Y Resolution: 72 dots per inch<br />
Resolution Unit: Inch<br />
Software: Adobe Photoshop CS3 Windows<br />
Date/Time: 2008:04:15 09:15:42<br />
F-Number: F2.8<br />
Date/Time Original: 2007:11:08 12:26:54<br />
Date/Time Digitized: 2007:11:08 12:26:54<br />
Color Space: sRGB<br />
Exif Image Width: 1200 pixels<br />
Exif Image Height: 900 pixels<br />
Unknown tag (0xa500): 2.2<br />
Compression: JPEG (old-style)<br />
Thumbnail Offset: 442 bytes<br />
Thumbnail Length: 8874 bytes<br />
Thumbnail Data: [8874 bytes of thumbnail data]</p>
<h3>JpegSegmentReader class implementation</h3>
<p><strong>Code:</strong></p>
<blockquote>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('12011');">[<span id="12011_symbol">-</span>]</a></span><span class="codebox_left"><span id="l120code11"><a href="javascript:;" onclick="javascript:showCodeTxt('120code11'); return false;">View Code</a> COLDFUSION</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="12011"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="code" id="120code11"><pre>segmentReaderObj = createObject(&quot;java&quot;,&quot;com.drew.imaging.jpeg.JpegSegmentReader&quot;);
segmentReader = segmentReaderObj.init(createObject(&quot;java&quot;,&quot;java.io.File&quot;).init(expandPath(&quot;./&quot;)&amp;amp;photoname));
exifSegment = segmentReader.readSegment(segmentReaderObj.SEGMENT_APP1);
iptcSegment = segmentReader.readSegment(segmentReaderObj.SEGMENT_APPD);
metadataObj = createObject(&quot;java&quot;,&quot;com.drew.metadata.Metadata&quot;);
exifReaderObj = createObject(&quot;java&quot;,&quot;com.drew.metadata.exif.ExifReader&quot;);
iptcReaderObj = createObject(&quot;java&quot;,&quot;com.drew.metadata.iptc.IptcReader&quot;);
metadata = metadataObj.init();
exifreader = exifReaderObj.init(exifSegment);
exifdata = exifreader.extract(metadata);
if (structKeyExists(variables,'iptcsegment')){
    iptcdata = iptcReaderObj.init(iptcSegment).extract(metadata);
}
&nbsp;
//write out the exif data
directories = exifdata.getDirectoryIterator();
while (directories.hasNext()){
    directory = directories.next();
    tags = directory.getTagIterator();
    while (tags.hasNext()) {
         tag = tags.next();
         WriteOutput(tag.getTagName()&amp;amp;': '&amp;amp;tag.getDescription()&amp;amp;'');
    }
}
//write out the iptc data
if (structKeyExists(variables,'iptcsegment')){
    directories = iptcdata.getDirectoryIterator();
    while (directories.hasNext()){
        directory = directories.next();
        tags = directory.getTagIterator();
        while (tags.hasNext()) {
             tag = tags.next();
             WriteOutput(tag.getTagName()&amp;amp;': '&amp;amp;tag.getDescription()&amp;amp;'');
        }
    }
}</pre></td></tr></table></div>

</blockquote>
<p><strong>Output:</strong><br />
Make: Apple<br />
Model: iPhone<br />
Orientation: Top, left side (Horizontal / normal)<br />
X Resolution: 72 dots per inch<br />
Y Resolution: 72 dots per inch<br />
Resolution Unit: Inch<br />
Software: Adobe Photoshop CS3 Windows<br />
Date/Time: 2008:04:15 09:15:42<br />
F-Number: F2.8<br />
Date/Time Original: 2007:11:08 12:26:54<br />
Date/Time Digitized: 2007:11:08 12:26:54<br />
Color Space: sRGB<br />
Exif Image Width: 1200 pixels<br />
Exif Image Height: 900 pixels<br />
Unknown tag (0xa500): 2.2<br />
Compression: JPEG (old-style)<br />
Thumbnail Offset: 442 bytes<br />
Thumbnail Length: 8874 bytes<br />
Thumbnail Data: [8874 bytes of thumbnail data]<br />
Directory Version: -23<br />
Make: Apple<br />
Model: iPhone<br />
Orientation: Top, left side (Horizontal / normal)<br />
X Resolution: 72 dots per inch<br />
Y Resolution: 72 dots per inch<br />
Resolution Unit: Inch<br />
Software: Adobe Photoshop CS3 Windows<br />
Date/Time: 2008:04:15 09:15:42<br />
F-Number: F2.8<br />
Date/Time Original: 2007:11:08 12:26:54<br />
Date/Time Digitized: 2007:11:08 12:26:54<br />
Color Space: sRGB<br />
Exif Image Width: 1200 pixels<br />
Exif Image Height: 900 pixels<br />
Unknown tag (0xa500): 2.2<br />
Compression: JPEG (old-style)<br />
Thumbnail Offset: 442 bytes<br />
Thumbnail Length: 8874 bytes<br />
Thumbnail Data: [8874 bytes of thumbnail data]<br />
Directory Version: -23</p>
<h3>JpegMetadataReader class implementation</h3>
<p><strong>Code:</strong></p>
<blockquote>

<div class="wp_codebox_msgheader"><span class="codebox_right"><a href="javascript:;" onclick="toggle_collapse('12012');">[<span id="12012_symbol">-</span>]</a></span><span class="codebox_left"><span id="l120code12"><a href="javascript:;" onclick="javascript:showCodeTxt('120code12'); return false;">View Code</a> COLDFUSION</span></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="12012"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="120code12"><pre>metadataReaderObj = createObject(&quot;java&quot;,&quot;com.drew.imaging.jpeg.JpegMetadataReader&quot;);
metadata = metadataReaderObj.readMetadata(createObject(&quot;java&quot;,&quot;java.io.File&quot;).init(expandPath(&quot;./&quot;)&amp;amp;photoname));
//write out the exif data
directories = metadata.getDirectoryIterator();
while (directories.hasNext()){
    directory = directories.next();
    tags = directory.getTagIterator();
    while (tags.hasNext()) {
         tag = tags.next();
         //WriteOutput(tag.getTagName()&amp;amp;': '&amp;amp;tag.getDescription()&amp;amp;'');
        WriteOutput(tag.toString()&amp;amp;'');
    }
}</pre></td></tr></table></div>

</blockquote>
<p><strong>Output:</strong><br />
[Exif] Make - Apple<br />
[Exif] Model - iPhone<br />
[Exif] Orientation - Top, left side (Horizontal / normal)<br />
[Exif] X Resolution - 72 dots per inch<br />
[Exif] Y Resolution - 72 dots per inch<br />
[Exif] Resolution Unit - Inch<br />
[Exif] Software - Adobe Photoshop CS3 Windows<br />
[Exif] Date/Time - 2008:04:15 09:15:42<br />
[Exif] F-Number - F2.8<br />
[Exif] Date/Time Original - 2007:11:08 12:26:54<br />
[Exif] Date/Time Digitized - 2007:11:08 12:26:54<br />
[Exif] Color Space - sRGB<br />
[Exif] Exif Image Width - 1200 pixels<br />
[Exif] Exif Image Height - 900 pixels<br />
[Exif] Unknown tag (0xa500) - 2.2<br />
[Exif] Compression - JPEG (old-style)<br />
[Exif] Thumbnail Offset - 442 bytes<br />
[Exif] Thumbnail Length - 8874 bytes<br />
[Exif] Thumbnail Data - [8874 bytes of thumbnail data]<br />
[Iptc] Directory Version - -23<br />
[Jpeg] Data Precision - 8 bits<br />
[Jpeg] Image Height - 900 pixels<br />
[Jpeg] Image Width - 1200 pixels<br />
[Jpeg] Number of Components - 3<br />
[Jpeg] Component 1 - Y component: Quantization table 0, Sampling factors 1 horiz/1 vert<br />
[Jpeg] Component 2 - Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert<br />
[Jpeg] Component 3 - Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert</p>
<h3>Conclusion</h3>
<p>In summary, it appears that there is not a consistent and reliable way to determine the resolution of an image using CF.  I am aware that there are external tools and libraries outside of Java and CF that I could use to obtain this information, such as using imageMagik, however, I have not attempted any of these approaches.</p>
<p>Maybe I am wrong with my approaches and implementations, and would love to hear any suggestions, thoughts, and experiences you have had with EXIF metadata or determining the resolution of an image using ColdFusion.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.brianflove.com/articles/2008/04/17/jpeg-resolution-via-exif-metadata/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
