<?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>Saturnboy &#187; iPhone</title>
	<atom:link href="http://saturnboy.com/tag/iphone/feed/" rel="self" type="application/rss+xml" />
	<link>http://saturnboy.com</link>
	<description>Code, Work, and Life</description>
	<lastBuildDate>Thu, 01 Mar 2012 22:35:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Perfect Gradients for Perfect Buttons</title>
		<link>http://saturnboy.com/2010/05/perfect-gradients-perfect-buttons/</link>
		<comments>http://saturnboy.com/2010/05/perfect-gradients-perfect-buttons/#comments</comments>
		<pubDate>Tue, 11 May 2010 03:21:02 +0000</pubDate>
		<dc:creator>justin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://saturnboy.com/?p=1334</guid>
		<description><![CDATA[Photoshop does this annoying thing where purely vertical gradients have some horizontal variation. Yes, it&#8217;s usually only plus or minus one bit of color, but it offends! I&#8217;ve battled Photoshop for a while on this, but I just can&#8217;t seem to get exactly what I want out of it. So to make a perfect gradient, [...]]]></description>
			<content:encoded><![CDATA[<p>Photoshop does this annoying thing where purely vertical gradients have some horizontal variation.  Yes, it&#8217;s usually only plus or minus one bit of color, but it offends!  I&#8217;ve battled Photoshop for a while on this, but I just can&#8217;t seem to get <b>exactly</b> what I want out of it.  So to make a perfect gradient, I decided to write some code.  The requirements are simple: given a starting color and a set of deltas, output a perfect gradient.</p>
<p class="bottom">Here are some quick examples:</p>
<div class="span-14 last">
<div class="span-1 comm-idx">1</div>
<div class="span-3">
<img src="http://saturnboy.com/proj/php/perfect_gradient/gradient1.png" alt="gradient1" title="gradient1" width="60" height="100" />
</div>
<div class="prepend-1 span-1 comm-idx">2</div>
<div class="span-3">
<img src="http://saturnboy.com/proj/php/perfect_gradient/gradient2.png" alt="gradient2" title="gradient2" width="60" height="100" />
</div>
<div class="prepend-1 span-1 comm-idx">3</div>
<div class="span-3 last">
<img src="http://saturnboy.com/proj/php/perfect_gradient/gradient3.png" alt="gradient3" title="gradient3" width="60" height="100" />
</div>
</div>
<div class="span-14 last">
<div class="prepend-1 span-3"><b>#000000</b><br />4, 1, 0.25</div>
<div class="prepend-2 span-3"><b>#eeeeff</b><br />-2.2, -1, -0.3</div>
<div class="prepend-2 span-3 last"><b>#ff0099</b><br />-1, 0, 1</div>
</div>
<div class="span-14 last">&nbsp;</div>
<p class="bottom">If we zoom in on example #1, which starts with black (#000000) and has deltas of 4, 1, 0.25, we see the following:</p>
<div class="prepend-1 span-13 last">
<img src="http://saturnboy.com/proj/php/perfect_gradient/gradient-diagram.png" alt="zoomed gradient" title="zoomed gradient" width="252" height="200" />
</div>
<div class="span-14 last">&nbsp;</div>
<p>The diagram shows the first ten rows of the gradient.  The delta values are accumulated with each row, and only the whole part of the resulting color value is used (aka I take the <b>floor</b> of each color bit).  So in this example, using the fractional delta of 0.25 results in exactly one additional blue bit every four rows.  Ahhh, perfect!</p>
<h3>The Code</h3>
<p class="bottom">No need to <a href="http://saturnboy.com/2010/04/the-schizophrenic-programmer/">use some fancy new language</a>, I wrote a simple PHP program to handle commandline input and output a perfect PNG gradient.  The interesting part is the function that generates and saves the gradient:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> build_image<span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #339933;">,</span> <span style="color: #000088;">$w</span><span style="color: #339933;">,</span> <span style="color: #000088;">$h</span><span style="color: #339933;">,</span> <span style="color: #000088;">$color</span><span style="color: #339933;">,</span> <span style="color: #000088;">$delta</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$img</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imagecreatetruecolor</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #339933;">,</span> <span style="color: #000088;">$h</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imagecolorallocate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$img</span><span style="color: #339933;">,</span> <span style="color: #000088;">$color</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$color</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$color</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$d</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$delta</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$y</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$y</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$h</span><span style="color: #339933;">;</span> <span style="color: #000088;">$y</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">imagefilledrectangle</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$img</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #000088;">$w</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imagecolorallocate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$img</span><span style="color: #339933;">,</span>
      clamp<span style="color: #009900;">&#40;</span><span style="color: #990000;">floor</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$color</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$d</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      clamp<span style="color: #009900;">&#40;</span><span style="color: #990000;">floor</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$color</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$d</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      clamp<span style="color: #009900;">&#40;</span><span style="color: #990000;">floor</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$color</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$d</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$d</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$d</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$delta</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$d</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$delta</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$d</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$delta</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #990000;">imagepng</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$img</span><span style="color: #339933;">,</span> <span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">imagedestroy</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$img</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The code is straight forward.  First, create the image via <code>imagecreatetruecolor()</code>.  Then, starting with the starting color, draw a one pixel tall rectangle for each row of the image.  The next row&#8217;s color is computed in each iteration by adding the accumulated delta to the starting color.  Finally, output the image as a PNG via <code>imagepng()</code> and free the memory.  The complete php source can be downloaded <a href="http://saturnboy.com/proj/php/perfect_gradient/gradient.php.gz">here</a>.</p>
<h3>Button Time </h3>
<p>Once we have our perfect gradient engine in place, it&#8217;s time to make some perfect buttons.  To achieve the standard <i>glass button</i> look-and-feel, I typically fuse two gradients together: light on the top, dark on the bottom.</p>
<p class="bottom">Here are the two halves of a pretty red button, along with their starting color and deltas:</p>
<div class="span-14 last">
<div class="prepend-1 span-3 quiet">TOP</div>
<div class="prepend-2 span-3 last quiet">BOTTOM</div>
</div>
<div class="span-14 last">
<div class="prepend-1 span-3">
<img src="http://saturnboy.com/proj/php/perfect_gradient/red-top.png" alt="top" title="top" width="100" height="16" />
</div>
<div class="prepend-2 span-3 last">
<img src="http://saturnboy.com/proj/php/perfect_gradient/red-bottom.png" alt="bottom" title="bottom" width="100" height="16" />
</div>
</div>
<div class="span-14 last">
<div class="prepend-1 span-3"><b>#ff8080</b><br />-3,-3,-3</div>
<div class="prepend-2 span-3 last"><b>#d23c3c</b><br />-3,-3,-3</div>
</div>
<div class="span-14 last">&nbsp;</div>
<p class="bottom">And the two commandline invocations of <code>gradient.php</code> to create the gradients:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php gradient.php 100x16 ff8080 -<span style="color: #000000;">3</span>,-<span style="color: #000000;">3</span>,-<span style="color: #000000;">3</span> top.png
php gradient.php 100x16 d23c3c -<span style="color: #000000;">3</span>,-<span style="color: #000000;">3</span>,-<span style="color: #000000;">3</span> bottom.png</pre></div></div>

<p>If I want my buttons to be sexy, rounded corners are a must.  My favorite photoshop trick to create multiple rounded buttons is to use a rounded alpha-transparent button with each gradient as a clipping mask.  Using a clipping mask is a simple way to guarantee button geometry remains fixed while colors are changed.</p>
<p class="bottom">Here is the layers pane showing the two gradients fused together and used as a clipping mask for the rounded alpha-transparent button:</p>
<div class="prepend-1 span-13 last">
<img src="http://saturnboy.com/proj/php/perfect_gradient/layers-dialog.png" alt="clip mask" title="clip mask" width="220" height="177" />
</div>
<div class="span-14 last">&nbsp;</div>
<p class="bottom">The result is a horizontally stretchable gradient button, that doesn&#8217;t look half bad.  See for yourself:</p>
<div class="prepend-1 span-13 last">
<img src="http://saturnboy.com/proj/php/perfect_gradient/btn-red.png" alt="button" title="button" width="26" height="32" />
</div>
<div class="span-14 last">&nbsp;</div>
<h3>Custom UIButton</h3>
<p class="bottom">The final button asset can be used as desired, but here is a simple Objective-C example since I&#8217;ve been in iPhone world lately:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">UIButton <span style="color: #002200;">*</span>btn <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIButton buttonWithType<span style="color: #002200;">:</span>UIButtonTypeCustom<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>btn setFrame<span style="color: #002200;">:</span>CGRectMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">20</span>, <span style="color: #2400d9;">20</span>, <span style="color: #2400d9;">140</span>, <span style="color: #2400d9;">32</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>btn setBackgroundImage<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIImage imageNamed<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;btn-red.png&quot;</span><span style="color: #002200;">&#93;</span>
      stretchableImageWithLeftCapWidth<span style="color: #002200;">:</span><span style="color: #2400d9;">10.0</span>
      topCapHeight<span style="color: #002200;">:</span><span style="color: #2400d9;">0.0</span><span style="color: #002200;">&#93;</span> forState<span style="color: #002200;">:</span>UIControlStateNormal<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>btn setTitle<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;BUTTON&quot;</span> forState<span style="color: #002200;">:</span>UIControlStateNormal<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>btn setTitleColor<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIColor whiteColor<span style="color: #002200;">&#93;</span> forState<span style="color: #002200;">:</span>UIControlStateNormal<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>btn.titleLabel setFont<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIFont boldSystemFontOfSize<span style="color: #002200;">:</span><span style="color: #2400d9;">14</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>Create a new <code>UIButton</code> of type <code>UIButtonTypeCustom</code> and then set the button skin as the <code>backgroundImage</code>.  The horizontal stretchability is due to the <code>stretchableImageWithLeftCapWidth</code> and <code>topCapHeight</code>.</p>
<p class="bottom">Here is a screenshot from the iPhone simulator showing the button in action:</p>
<div class="prepend-1 span-13 last">
<img src="http://saturnboy.com/proj/php/perfect_gradient/screenshot.png" alt="screenshot" title="screenshot" width="326" height="486" />
</div>
<div class="span-14 last">&nbsp;</div>
<h5>Files</h5>
<ul>
<li><a href="http://saturnboy.com/proj/php/perfect_gradient/gradient.php.gz">gradient.php</a> &ndash; the perfect gradient engine</li>
<li><a href="http://saturnboy.com/proj/php/perfect_gradient/gradient-button.psd">gradient-button.psd</a> &ndash; the photoshop source for the red button image, including the rounded alpha-transparent button and fused red gradients</li>
<li><a href="http://saturnboy.com/proj/php/perfect_gradient/btn-red.png">btn-red.png</a> &ndash; the red button image</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://saturnboy.com/2010/05/perfect-gradients-perfect-buttons/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

