<?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>CocoAbyss</title>
	<atom:link href="http://www.cocoabyss.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cocoabyss.com</link>
	<description>iOS &#38; Mac OS programming</description>
	<lastBuildDate>Sun, 05 Feb 2012 12:04:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>qlImageSize now works for iPhone&#8217;s PNG</title>
		<link>http://www.cocoabyss.com/quicklook/qlimagesize-iphone-crushed-png/</link>
		<comments>http://www.cocoabyss.com/quicklook/qlimagesize-iphone-crushed-png/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 21:40:48 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[QuickLook]]></category>
		<category><![CDATA[libpng]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[pngcrush]]></category>
		<category><![CDATA[qlImageSize]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=341</guid>
		<description><![CDATA[As you may know, iPhone&#8217;s PNGs are crushed with a modified version of pngcrush, and so when you are trying to open them you get an error message. Of course, several tools exist to uncrush these files, but now with &#8230; <a href="http://www.cocoabyss.com/quicklook/qlimagesize-iphone-crushed-png/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As you may know, iPhone&#8217;s PNGs are crushed with a modified version of <a href="http://pmt.sourceforge.net/pngcrush/" target="_blank">pngcrush</a>, and so when you are trying to open them you get an error message. Of course, several tools exist to uncrush these files, but now with <strong>qlImageSize</strong> you can see their icon in the finder and also QuickLook them.<br />
<span id="more-341"></span><br />
To do this, my first attempt was to use an <code>NSTask</code> with the Apple&#8217;s <i>pngcrush</i> command line tool, like the following :</p>
<pre class="brush: objc; title: ; notranslate">/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush -revert-iphone-optimizations input.png decoded.png</pre>
<p>But, I was not satisfied for several reasons :</p>
<p><b>1.</b> Needed to copy the binary inside the plugin for people who don&#8217;t have dev tools installed.<br />
<b>2.</b> For each crushed PNG, a process was spawned to uncrush it.<br />
<b>3.</b> A temporary image was written to disk, read into memory then deleted.</p>
<p>I don&#8217;t call this very efficient because that&#8217;s a lot of work for such a small task. Then I thought, what&#8217;s better than <a href="http://www.libpng.org/" target="_blank">libpng</a> to work with PNGs ? <img src='http://www.cocoabyss.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So I coded a tiny library to uncrush an Apple&#8217;s PNG file and integrated it in <strong>qlImageSize</strong>. I&#8217;ll write a technical post about it later.</p>
<p><img src="http://www.cocoabyss.com/wp-content/uploads/2012/02/ql4.jpg" style="margin-left: auto; margin-right: auto; display: block;" /></p>
<p>I updated the code in my <a href="https://github.com/Nyx0uf/qlImageSize" target="_blank">github repo</a>.</p>
<p>The new compiled version is also available <a href="https://github.com/downloads/Nyx0uf/qlImageSize/qlImageSize.qlgenerator.zip" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/quicklook/qlimagesize-iphone-crushed-png/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Images dimensions in QuickLook</title>
		<link>http://www.cocoabyss.com/mac-os-x/images-dimensions-in-quicklook/</link>
		<comments>http://www.cocoabyss.com/mac-os-x/images-dimensions-in-quicklook/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 11:23:21 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[QuickLook]]></category>
		<category><![CDATA[CGImageSource]]></category>
		<category><![CDATA[dimension]]></category>
		<category><![CDATA[ImageIO]]></category>
		<category><![CDATA[Images]]></category>
		<category><![CDATA[size]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=338</guid>
		<description><![CDATA[I&#8217;m often looking for images dimensions, and most of the time I hit the spacebar to trigger QuickLook to see them, and each time I&#8217;m disappointed because it only displays the name of the file, which, we TOTALLY do NOT &#8230; <a href="http://www.cocoabyss.com/mac-os-x/images-dimensions-in-quicklook/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m often looking for images dimensions, and most of the time I hit the spacebar to trigger <strong>QuickLook</strong> to see them, and each time I&#8217;m disappointed because it only displays the name of the file, which, we <strong>TOTALLY</strong> do <strong>NOT</strong> care. Finally I end up opening the image with preview, just for some dimensions, <strong>it&#8217;s teh sux</strong>. So it was time to create a new Xcode project.<br />
<span id="more-338"></span><br />
The default behavior when you QuickLook an image looks like this<br />
<img src="http://www.cocoabyss.com/wp-content/uploads/2012/02/ql1.jpg" style="margin-left: auto; margin-right: auto; display: block;" /><br />
Having the name of the file as the window title is, in my opinion, <i><strong>totally useless</strong></i>.</p>
<p>So, after creating the QuickLook project, I took a look at <strong>QuickLook.h</strong>, and find this useful line of code :</p>
<pre class="brush: objc; title: ; notranslate">QL_EXPORT const CFStringRef kQLPreviewPropertyDisplayNameKey; // useful to customize the title of the QuickLook panel</pre>
<p>Awesome, just what I needed.<br />
Now finding the images dimensions is trivial with <i><strong>ImageIO</strong></i>, so let&#8217;s implement <code>GeneratePreviewForURL()</code>.</p>
<pre class="brush: objc; title: ; notranslate">OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
{
	CGImageSourceRef imgSrc = CGImageSourceCreateWithURL(url, NULL);
	if (!imgSrc)
	{
		QLPreviewRequestSetURLRepresentation(preview, url, contentTypeUTI, NULL);
		return -1;
	}
	CFDictionaryRef imgProperties = CGImageSourceCopyPropertiesAtIndex(imgSrc, 0, NULL);
	CFRelease(imgSrc);
	if (!imgProperties)
	{
		QLPreviewRequestSetURLRepresentation(preview, url, contentTypeUTI, NULL);
		return -1;
	}
	CFNumberRef w = CFDictionaryGetValue(imgProperties, kCGImagePropertyPixelWidth);
	int width = 0;
	CFNumberGetValue(w, kCFNumberIntType, &amp;width);
	CFNumberRef h = CFDictionaryGetValue(imgProperties, kCGImagePropertyPixelHeight);
	int height = 0;
	CFNumberGetValue(h, kCFNumberIntType, &amp;height);
	CFRelease(imgProperties);

	CFStringRef keys[1] = {kQLPreviewPropertyDisplayNameKey};
	CFStringRef values[1] = {CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR(&quot;%dx%d&quot;), width, height)};
	CFDictionaryRef properties = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, 1, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
	QLPreviewRequestSetURLRepresentation(preview, url, contentTypeUTI, properties);

	CFRelease(values[0]);
	CFRelease(properties);

	return noErr;
}</pre>
<p>Ok, we are almost done, we need to implement the <code>GenerateThumbnailForURL()</code> function, otherwise all images icon will become generic. Luckily, it&#8217;s only one line of code :</p>
<pre class="brush: objc; title: ; notranslate">OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
{
	QLThumbnailRequestSetImageAtURL(thumbnail, url, NULL);
	return noErr;
}</pre>
<p>Let&#8217;s take a look at the result :<br />
<img src="http://www.cocoabyss.com/wp-content/uploads/2012/02/ql2.jpg" style="margin-left: auto; margin-right: auto; display: block;" /><br />
Ok, that&#8217;s more like it.</p>
<p>I put the Xcode project on my <a href="https://github.com/Nyx0uf/qlImageSize" target="_blank">github</a>.</p>
<p>For non-devs, <a href="https://github.com/downloads/Nyx0uf/qlImageSize/qlImageSize.qlgenerator.zip" target="_blank">here is a direct link to the plugin</a>.<br />
To install it, simply unzip the file and place <strong>qlImageSize.qlgenerator</strong> in your <i>~/Library/QuickLook</i> or <i>/Library/QuickLook</i> folder.</p>
<p>To force <strong>QuickLook</strong> to reload the plugins open <strong>Terminal.app</strong> and type :</p>
<pre class="brush: bash; title: ; notranslate">qlmanage -r</pre>
<p><b>EDIT :</b> I added the file size.</p>
<div id="edit2"><b>EDIT 2 :</b></div>
<p>If you build from the sources, I added an option to display the image extension inside the icons in the finder. The extension is based on the <a href="http://en.wikipedia.org/wiki/Uniform_Type_Identifier" target="_blank">Uniform Type Identifier (UTI)</a> of the image.</p>
<p><img src="http://www.cocoabyss.com/wp-content/uploads/2012/02/ql3.jpg" style="margin-left: auto; margin-right: auto; display: block;" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/mac-os-x/images-dimensions-in-quicklook/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>New class for NYXImagesKit : NYXProgressiveImageView</title>
		<link>http://www.cocoabyss.com/uikit/nyxprogressiveimageview-nyximageskit/</link>
		<comments>http://www.cocoabyss.com/uikit/nyxprogressiveimageview-nyximageskit/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 18:41:19 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[Core Graphics]]></category>
		<category><![CDATA[UIKit]]></category>
		<category><![CDATA[CGImageSource]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[ImageIO]]></category>
		<category><![CDATA[Images]]></category>
		<category><![CDATA[NYXImagesKit]]></category>
		<category><![CDATA[UIImage]]></category>
		<category><![CDATA[UIImageView]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=336</guid>
		<description><![CDATA[Some time ago, I showed how to progressively display an image while it was being downloaded using ImageIO.framework. Today I created a simple subclass of UIImageView in NYXImagesKit to take advantage of this feature. As it&#8217;s a subclass of UIImageView, &#8230; <a href="http://www.cocoabyss.com/uikit/nyxprogressiveimageview-nyximageskit/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Some time ago, I showed how to <a href="http://www.cocoabyss.com/mac-os-x/progressive-image-download-imageio/" target="_blank">progressively display an image</a> while it was being downloaded using <strong>ImageIO.framework</strong>. Today I created a simple subclass of <code>UIImageView</code> in <strong>NYXImagesKit</strong> to take advantage of this feature.<br />
<span id="more-336"></span><br />
As it&#8217;s a subclass of <code>UIImageView</code>, it&#8217;s really easy to use. Just do as you usually do, and just call the <code>loadImageAtURL:</code> method when you want to download and display an image.</p>
<pre class="brush: objc; title: ; notranslate">NYXProgressiveImageView* iv = [[NYXProgressiveImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 640.0f)];
[iv loadImageAtURL:[NSURL urlWithString:@&quot;http://www.image.url&quot;]];
</pre>
<p>There is also a protocol with 2 optional methods, the first will be called if the download was successful and will contain the downloaded image object. If you want to implement some sort of caching, it&#8217;s the place.</p>
<pre class="brush: objc; title: ; notranslate">-(void)imageDownloadCompletedWithImage:(UIImage*)img;</pre>
<p>The second will be called if the download failed, and will contain the downloaded data or <code>nil</code></p>
<pre class="brush: objc; title: ; notranslate">-(void)imageDownloadFailedWithData:(NSData*)data;</pre>
<p>The code for <strong>NYXImagesKit</strong> is available on my <a href="https://github.com/Nyx0uf/NYXImagesKit">github page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/uikit/nyxprogressiveimageview-nyximageskit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NYXImagesUtilities becomes NYXImagesKit</title>
		<link>http://www.cocoabyss.com/coregraphics/nyximagesutilities-becomes-nyximageskit/</link>
		<comments>http://www.cocoabyss.com/coregraphics/nyximagesutilities-becomes-nyximageskit/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 18:06:24 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[Core Graphics]]></category>
		<category><![CDATA[Core Image]]></category>
		<category><![CDATA[CGImage]]></category>
		<category><![CDATA[NYXImagesKit]]></category>
		<category><![CDATA[NYXImagesUtilities]]></category>
		<category><![CDATA[performances]]></category>
		<category><![CDATA[UIImage]]></category>
		<category><![CDATA[vDSP]]></category>
		<category><![CDATA[vImage]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=334</guid>
		<description><![CDATA[Few months ago I released NYXImagesUtilities, a set of categories to perform various operations on UIImage objects such as resizing, applying filters and more. Since then I didn&#8217;t update it, but today I&#8217;m proud to announce that I&#8217;ve been working &#8230; <a href="http://www.cocoabyss.com/coregraphics/nyximagesutilities-becomes-nyximageskit/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Few months ago I released <a href="http://www.cocoabyss.com/uikit/introducing-nyximagesutilities-ios/" target="_blank">NYXImagesUtilities</a>, a set of categories to perform various operations on <code>UIImage</code> objects such as resizing, applying filters and more. Since then I didn&#8217;t update it, but today I&#8217;m proud to announce that I&#8217;ve been working a lot on it lately to add new stuff and to focus on performances. For this occasion I decided to rename it <em><strong>NYXImagesKit</strong></em><br />
<span id="more-334"></span></p>
<h1>Introduction</h1>
<p>The main idea was to focus on performances, how could I improve them ?</p>
<p>It turned out that Apple brought <a href="http://developer.apple.com/library/ios/#documentation/Accelerate/Reference/AccelerateFWRef/_index.html#//apple_ref/doc/uid/TP40009465" target="_blank">Accelerate.framework</a> on iOS 4 so we can take advantages of <a href="http://developer.apple.com/library/ios/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html#//apple_ref/doc/uid/TP40009464" target="_blank">vDSP</a> functions.<br />
And it&#8217;s even better on <i>iOS 5</i>, because we now have access to <a href="http://developer.apple.com/library/ios/DOCUMENTATION/GraphicsImaging/Conceptual/CoreImaging/CoreImage.pdf" target="_blank">Core Image</a> and <a href="http://developer.apple.com/library/ios/#documentation/Performance/Conceptual/vImage/Introduction/Introduction.html#//apple_ref/doc/uid/TP30001001" target="_blank">vImage</a> APIs in Accelerate.</p>
<p>The second idea was to add some functionalities, especially filters because there were only 3, now there are <strong>11</strong> !</p>
<p>The code still requires at least iOS 4.2, and is fully <strong>ARC</strong> enabled. The license has not changed and is <a href="http://www.opensource.org/licenses/bsd-license.php" target="_blank">Simplified BSD</a>.</p>
<h1>So, what&#8217;s new ?!</h1>
<h2>I. UIImage+Enchancing</h2>
<p>This is a new category which works only on iOS 5 because it uses <strong>Core Image</strong>. It is composed of 2 methods :</p>
<p><code>-(UIImage*)autoEnhance;</code><br />
<code>-(UIImage*)redEyeCorrection;</code></p>
<p>The names are pretty straitforward, to guess what these methods do.</p>
<h2>II. New filters</h2>
<p>There are <b>8</b> new filters, let&#8217;s review them with Sarah Shahi as a sample image (click to enlarge).</p>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p><b>1. Brighten</b></p>
<p>This filter allow you to brighten or darken an image.</p>
<pre class="brush: objc; title: ; notranslate">UIImage* brightened = [myImage brightenWithValue:13.0f];</pre>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_brighten.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_brighten_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p>The value should be in the range <b><i>-255, 255</i></b>.</p>
<p><b>2. Contrast adjustment</b></p>
<pre class="brush: objc; title: ; notranslate">UIImage* contrasted = [myImage contrastAdjustmentWithValue:37.0f];</pre>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_contrast.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_contrast_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p>The value should be in the range <b><i>-255, 255</i></b>.</p>
<p><b>3. Edge detection</b></p>
<p>This filter is used to detect edges on an image.</p>
<pre class="brush: objc; title: ; notranslate">UIImage* edge = [myImage edgeDetectionWithBias:0];</pre>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_edge.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_edge_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p><i>The bias value is only used on iOS 5.</i></p>
<p><b>4. Emboss</b></p>
<pre class="brush: objc; title: ; notranslate">UIImage* emboss = [myImage embossWithBias:0];</pre>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_emboss.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_emboss_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p><i>The bias value is only used on iOS 5.</i></p>
<p><b>5. Gamma correction</b></p>
<pre class="brush: objc; title: ; notranslate">UIImage* gammaCorrected = [myImage gammaCorrectionWithValue:2.0f];</pre>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_gamma.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_gamma_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p>Good values for the gamma correction are in the range <b><i>0.01, 8</i></b></p>
<p><b>6. Invert</b></p>
<p>This filter invert the colors of an image.</p>
<pre class="brush: objc; title: ; notranslate">UIImage* inverted = [myImage invert];</pre>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_invert.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_invert_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p><b>7. Sharpen</b></p>
<pre class="brush: objc; title: ; notranslate">UIImage* sharpened = [myImage sharpenWithBias:0];</pre>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_sharpen.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_sharpen_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p><i>The bias value is only used on iOS 5.</i></p>
<p><b>8. Unsharpen</b></p>
<pre class="brush: objc; title: ; notranslate">UIImage* unsharpened = [myImage unsharpenWithBias:0];</pre>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_unsharpen.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_unsharpen_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p><i>The bias value is only used on iOS 5.</i></p>
<h2>III. New rotation methods</h2>
<p>There are 2 new methods to rotate an image but there are only availabe on iOS 5 because they use <strong>vImage</strong>.</p>
<p><code>-(UIImage*)rotateImagePixelsInDegrees:(float)degrees;</code><br />
<code>-(UIImage*)rotateImagePixelsInRadians:(float)radians;</code></p>
<p>The difference between the other rotation methods is that the dimensions of the image won&#8217;t change (here 640&#215;960), it&#8217;s the content that is being rotated, so the image is being truncated.</p>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_rotate.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_rotate_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<h2>IV. Saving to Photos.app</h2>
<p>I added a simple method in <strong>UIImage+Saving</strong> to save an <code>UIImage</code> to the Photos application.</p>
<pre class="brush: objc; title: ; notranslate">[myImage saveToPhotosAlbum];</pre>
<p><br/></p>
<h1>What changed ?</h1>
<p>So now let&#8217;s look at what as changed.</p>
<h2>I. Blurring</h2>
<p>I&#8217;m no longer using Jeff&#8217;s code to perform the gaussian blur, instead I rewrote the method using <strong>vDSP</strong> for <i>iOS 4</i>, and <strong>vImage</strong> for <i>iOS 5</i>.</p>
<p>Here is a quick benchmark on an iPhone 4S with the same image.</p>
<p>With the old method the average time to blur the image was <strong>4.0s</strong>, so it was very very slow.</p>
<p>On <i>iOS 4</i> with <strong>vDSP</strong> it took about <strong>0.67s</strong>, <strong>6x</strong> times faster.</p>
<p>On <i>iOS 5</i> with <strong>vImage</strong> it took about <strong>0.19s</strong>, <strong>21x</strong> times faster.</p>
<p>So it&#8217;s a very big win for this method.</p>
<h2>II. Sepia filter</h2>
<p>For <i>iOS 4</i>, I rewrote it using <strong>vDSP</strong>, it is more than <strong>1.6x</strong> faster than before, so it&#8217;s a bit better.</p>
<p>The big win is on <i>iOS 5</i>, because it uses <strong>Core Image</strong>. As a result it is <strong>1.6x</strong> faster than the <i>iOS 4</i> method, that&#8217;s <strong>2.5x</strong> faster than my original method.<br />
The other great thing is that the sepia tone from <strong>Core Image</strong> are nicer than with the manual method.</p>
<p><a rel="lightbox" href="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_sepia.jpg"><img src="http://www.cocoabyss.com/wp-content/uploads/2012/01/sarahshahi_sepia_thumb.jpg" style="margin-left:auto;margin-right:auto;display:block;"/></a></p>
<p><br/></p>
<h1>Conclusion</h1>
<p>I hope you &#8216;ll like this new release, and feel free to contribute !</p>
<p>As before, you can get the code on <a href="https://github.com/Nyx0uf/NYXImagesKit" target="_blank">github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/coregraphics/nyximagesutilities-becomes-nyximageskit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatic Network Activity Indicator with NSURLConnection</title>
		<link>http://www.cocoabyss.com/foundation/automatic-network-activity-indicator-with-nsurlconnection/</link>
		<comments>http://www.cocoabyss.com/foundation/automatic-network-activity-indicator-with-nsurlconnection/#comments</comments>
		<pubDate>Tue, 06 Dec 2011 20:43:29 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[Foundation]]></category>
		<category><![CDATA[network activity indicator]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[NSURLConnection]]></category>
		<category><![CDATA[Swizzling]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=332</guid>
		<description><![CDATA[It&#8217;s very common to use networking APIs on mobile devices because of their nature. On iOS I&#8217;m sure every programmer is familiar with NSURLConnection and the network activity indicator, which we are suppose to show when we do networking, and &#8230; <a href="http://www.cocoabyss.com/foundation/automatic-network-activity-indicator-with-nsurlconnection/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s very common to use networking APIs on mobile devices because of their nature. On iOS I&#8217;m sure every programmer is familiar with NSURLConnection and the network activity indicator, which we are suppose to show when we do networking, and managing it is a pain in the ass. Let&#8217;s correct this.<br />
<span id="more-332"></span></p>
<h2>Keeping the Network Activity Indicator in sync</h2>
<p>I&#8217;m pretty sure you encountered this problem, how can you keep the indicator synced in a multithreaded application ? Showing it when an operation start is easy, but how do we know when to hide it ?<br />
We can easily solve this problem with a category on <code>UIApplication</code> that counts the number of active connections and show the indicator when this number is positive.</p>
<p>So let&#8217;s begin with the header</p>
<pre class="brush: objc; title: ; notranslate">@interface UIApplication (NYX_NetworkActivityIndicator)

-(void)nyx_pushNetworkActivity;
-(void)nyx_popNetworkActivity;

@end</pre>
<p>We just declare two methods, one to increase the counter and the other to decrease it.</p>
<p>Now the implementation.</p>
<pre class="brush: objc; title: ; notranslate">#import &quot;UIApplication+NetworkActivity.h&quot;

static NSInteger __nyxNetworkActivityCount = 0;

@implementation UIApplication (NYX_NetworkActivityIndicator)

-(void)nyxRefreshNetworkActivityIndicator
{
	if (![NSThread isMainThread])
	{
		[self performSelectorOnMainThread:@selector(nyxRefreshNetworkActivityIndicator) withObject:nil waitUntilDone:NO];
		return;
	}
	self.networkActivityIndicatorVisible = (__nyxNetworkActivityCount &gt; 0);
}

-(void)nyx_pushNetworkActivity
{
	@synchronized(self)
	{
		__nyxNetworkActivityCount++;
	}
	[self nyxRefreshNetworkActivityIndicator];
}

-(void)nyx_popNetworkActivity
{
	@synchronized(self)
	{
		if (__nyxNetworkActivityCount &gt; 0)
			__nyxNetworkActivityCount--;
		else
			__nyxNetworkActivityCount = 0;
		[self nyxRefreshNetworkActivityIndicator];
	}
}

@end</pre>
<p>First we need to declare a static variable to hold the count. Then, the push and pop methods just increment or decrement this variable and call a private method that show or hide the network activity indicator accordingly.</p>
<p>Add the header in your <strong>Prefix.pch</strong> so that you can access these methods everywhere in your project.</p>
<p>Now before starting a NSURLConnection you call</p>
<pre class="brush: objc; title: ; notranslate">[[UIApplication sharedApplication] nyx_pushNetworkActivity];</pre>
<p>and when you are done</p>
<pre class="brush: objc; title: ; notranslate">[[UIApplication sharedApplication] nyx_popNetworkActivity];</pre>
<p>No more trouble managing this activity indicator across multiple threads, but wouldn&#8217;t it be great if the indicator just showed up when a <code>NSURLConnection</code> start, without the need for us to do it ?</p>
<h2>Automatically showing the Network Activity Indicator when a connection start</h2>
<p>This part is a bit more tricky, in order to achieve this we are gonna use <strong>method swizzling</strong>, if you are not familiar with this you can read this <a href="http://www.mikeash.com/pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html">great post</a> by <a href="https://twitter.com/#!/mikeash">Mike Ash</a>.</p>
<p>We are gonna swizzle two <code>NSURLConnection</code>&#8216;s method :</p>
<p>- <code>initWithRequest:delegate:startImmediately:</code> to start the indicator.<br />
- <code>dealloc</code> to stop the indicator. ARC forbids us to use a selector on <code>dealloc</code>, so we must trick it with <code>NSSelectorFromString()</code>.</p>
<p>Create a new category on <code>NSURLConnection</code>, there is nothing in the header so we skip directly to the implementation.</p>
<p>First we include the proper header and then we just take the <i>Swizzle</i> function in Mike&#8217;s post.</p>
<pre class="brush: objc; title: ; notranslate">#import &quot;NSURLConnection+AutomaticIndicator.h&quot;
#import &lt;objc/runtime.h&gt;

void swizzle_instance_method(Class c, SEL origSEL, SEL overrideSEL)
{
	Method origMethod = class_getInstanceMethod(c, origSEL);
	Method overrideMethod = class_getInstanceMethod(c, overrideSEL);
	if (class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod)))
		class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
	else
		method_exchangeImplementations(origMethod, overrideMethod);
}</pre>
<p>Then we need to create our two custom methods.</p>
<pre class="brush: objc; title: ; notranslate">-(id)nyxInitWithRequest:(NSURLRequest*)request delegate:(id)delegate startImmediately:(BOOL)startImmediately
{
	[[UIApplication sharedApplication] nyx_pushNetworkActivity];
	return [self nyxInitWithRequest:request delegate:delegate startImmediately:startImmediately];
}

-(void)nyxDealloc
{
	[[UIApplication sharedApplication] nyx_popNetworkActivity];
	[self nyxDealloc];
}</pre>
<p>Finally in the <strong>+(void)load</strong> method we swizzle.</p>
<pre class="brush: objc; title: ; notranslate">+(void)load
{
	swizzle_instance_method(self, @selector(initWithRequest:delegate:startImmediately:), @selector(nyxInitWithRequest:delegate:startImmediately:));
	swizzle_instance_method(self, NSSelectorFromString(@&quot;dealloc&quot;), @selector(nyxDealloc));
}</pre>
<p>Now just try to use a <code>NSURLConnection</code> with the method we just swizzled, you will see that the indicator shows up and disappears as you expect.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/foundation/automatic-network-activity-indicator-with-nsurlconnection/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SL-NTFS sources</title>
		<link>http://www.cocoabyss.com/misc/sl-ntfs-sources/</link>
		<comments>http://www.cocoabyss.com/misc/sl-ntfs-sources/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 09:44:03 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[SL-NTFS]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=331</guid>
		<description><![CDATA[Following my previous post on SL-NTFS several people asked me for the sources. So, here is a link to those. Consider the licence to something like Do what the fuck you want.]]></description>
			<content:encoded><![CDATA[<p>Following my <a href="http://www.cocoabyss.com/misc/lion-and-sl-ntfs/" target="_blank">previous post on SL-NTFS</a> several people asked me for the sources.</p>
<p>So, <a href="http://www.cocoabyss.com/wp-content/uploads/2011/11/SL-NTFS.zip">here is a link to those</a>.</p>
<p>Consider the licence to something like <i>Do what the fuck you want</i>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/misc/sl-ntfs-sources/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding misaligned images in Instruments</title>
		<link>http://www.cocoabyss.com/coding-practice/understanding-misaligned-images-in-instruments/</link>
		<comments>http://www.cocoabyss.com/coding-practice/understanding-misaligned-images-in-instruments/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 21:08:15 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[Core Animation]]></category>
		<category><![CDATA[Core Graphics]]></category>
		<category><![CDATA[UIKit]]></category>
		<category><![CDATA[aliasing]]></category>
		<category><![CDATA[Images]]></category>
		<category><![CDATA[Instruments]]></category>
		<category><![CDATA[performances]]></category>
		<category><![CDATA[pixel]]></category>
		<category><![CDATA[tech talk]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=328</guid>
		<description><![CDATA[I attended the Berlin Tech Talk conference on november 2. The last talk was given by Michael Jurewitz and was titled Your iOS App Performance Hitlist. This talk was excellent, the best in my opinion (But that&#8217;s because I love &#8230; <a href="http://www.cocoabyss.com/coding-practice/understanding-misaligned-images-in-instruments/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I attended the Berlin Tech Talk conference on november 2. The last talk was given by <a href="https://twitter.com/#!/jury">Michael Jurewitz</a> and was titled <strong>Your iOS App Performance Hitlist</strong>. This talk was excellent, the best in my opinion (But that&#8217;s because I love talking about performances), and it was focused on using Instruments.<br />
<span id="more-328"></span><br />
The talk was divided in 3 parts :</p>
<p>1. Launch Quickly / Avoid Blocking Work<br />
2. Minimize Memory Usage<br />
3. Draw Efficiently</p>
<p>I&#8217;m not going to talk about the 2 firsts because they were pretty straightforward, and I didn&#8217;t learn much that I already knew here, but if you are interested you can check this <a href="http://oleb.net/blog/2011/11/ios5-tech-talk-michael-jurewitz-on-performance-measurement/" target="_blank">great post</a> by <a href="https://twitter.com/#!/olebegemann">Ole Begemann</a> and <a href="http://cyrilgodefroy.com/blog/2011/11/Apple-tech-talk-was-cool/" target="_blank">this one</a> by <a href="https://twitter.com/#!/cgodefroy">Cyril Godefroy</a>.</p>
<p>So let&#8217;s jump directly to the third topic, In the Core Animation instruments in the Debug options area there is a checkbox called <strong>Color Misaligned Images</strong>.</p>
<p><a rel="lightbox" href="http://cocoabyss.com/wp-content/uploads/2011/11/inst1.jpg" rel="nofollow"><img src="http://cocoabyss.com/wp-content/uploads/2011/11/inst1_thumb.jpg" alt="Core Animation instrument" style="margin-left:auto;margin-right:auto;display:block;" /></a></p>
<p>This option does 2 things :</p>
<p>1. It highlights <strong>scaled</strong> and <strong>stretched</strong> content in yellow. So <i>UIKit</i> elements (like <i>UIToolBar</i>, <i>UINavigationBar</i>&#8230;) will be highlighted, but no worry here, Apple uses stretching a lot for UIKit in order to consume less memory and reduce its size. You should look at <strong><i>YOUR</i></strong> things here.</p>
<p><img src="http://cocoabyss.com/wp-content/uploads/2011/11/inst2.jpg" alt="Stretched images" style="margin-left:auto;margin-right:auto;display:block;" /></p>
<p>2. It highlights <strong>misaligned</strong> images in magenta. But what the hell is a misaligned image ?</p>
<p>To put it simply, your screen has a resolution of 960&#215;640 pixels (or 480&#215;320 depending on your device), but UIKit and Core Graphics uses floating points values.<br />
When it comes time to render the content, these coordinates have to be mapped to the pixel grid of the screen before they are displayed.<br />
If your content is not aligned on integral coordinates it will require much more work from the GPU, and there is a big chance that your content will be aliased and looks really ugly.</p>
<p>So if you do some calculations to display, for example, an image gallery, always cast the coordinates to integer values to avoid these kind of trouble.</p>
<p><img src="http://cocoabyss.com/wp-content/uploads/2011/11/inst3.jpg" alt="Misaligned images" style="margin-left:auto;margin-right:auto;display:block;" /></p>
<p>Let&#8217;s finish with a quote from <i>Michael Jurewitz</i>.</p>
<blockquote><p>&#8220;If you have a label that is aliased, I guarantee you at 100% that it is misaligned.&#8221;</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/coding-practice/understanding-misaligned-images-in-instruments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[iOS 5] Bug fix for CGImageSourceCreateIncremental</title>
		<link>http://www.cocoabyss.com/uikit/ios-5-bug-fix-cgimagesourcecreateincremental/</link>
		<comments>http://www.cocoabyss.com/uikit/ios-5-bug-fix-cgimagesourcecreateincremental/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 10:00:22 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[Core Graphics]]></category>
		<category><![CDATA[UIKit]]></category>
		<category><![CDATA[bitmap context]]></category>
		<category><![CDATA[CGImage]]></category>
		<category><![CDATA[CGImageSource]]></category>
		<category><![CDATA[ImageIO]]></category>
		<category><![CDATA[iOS 5]]></category>
		<category><![CDATA[UIImage]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=325</guid>
		<description><![CDATA[In a previous post I showed how to create a progressive image download using ImageIO.framework available since iOS 4. In that post I said that there was a problem concerning the progressive display of non-PNG images because they were malformed. &#8230; <a href="http://www.cocoabyss.com/uikit/ios-5-bug-fix-cgimagesourcecreateincremental/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In a previous post I showed how to create a <a href="http://www.cocoabyss.com/mac-os-x/progressive-image-download-imageio/">progressive image download</a> using <code>ImageIO.framework</code> available since iOS 4. In that post I said that there was a problem concerning the progressive display of non-PNG images because they were malformed. Fortunately the fix was easy and consisted to simply render the partial image in a bitmap context and get it back, but well, it consumes CPU for nothin&#8217;.<br />
<span id="more-325"></span><br />
The code looked like this :</p>
<pre class="brush: objc; title: ; notranslate">-(CGImageRef)createTransitoryImage:(CGImageRef)partialImg
{
	const size_t height = CGImageGetHeight(partialImg);
	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
	CGContextRef bmContext = CGBitmapContextCreate(NULL, _fullWidth, _fullHeight, 8, _fullWidth * 4, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
	CGColorSpaceRelease(colorSpace);
	if (!bmContext)
	{
		NSLog(@&quot;fail creating context&quot;);
		return NULL;
	}
	CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = _fullWidth, .size.height = height}, partialImg);
	CGImageRef goodImageRef = CGBitmapContextCreateImage(bmContext);
	CGContextRelease(bmContext);
	return goodImageRef;
}</pre>
<p>And corrected this problem :<br />
<img src="http://www.cocoabyss.com/wp-content/uploads/2011/05/pid_bug_thumb.jpg" alt="Malformed image" style="margin-left:auto;margin-right:auto;display:block;" /></p>
<p><strong>It appears to be fixed on iOS 5</strong>, we don&#8217;t need to render other image types in a bitmap context, so it&#8217;s a pretty good thing. <img src='http://www.cocoabyss.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/uikit/ios-5-bug-fix-cgimagesourcecreateincremental/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[iOS 5] Twitter integration framework</title>
		<link>http://www.cocoabyss.com/misc/ios-5-twitter-integration-framework/</link>
		<comments>http://www.cocoabyss.com/misc/ios-5-twitter-integration-framework/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 08:00:04 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[iOS 5]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=324</guid>
		<description><![CDATA[One of the new feature that comes with iOS 5 is the native Twitter integration. You just have to register your account(s) in the Settings application and you are done, you can easily tweet your photos, links&#8230; with a nice &#8230; <a href="http://www.cocoabyss.com/misc/ios-5-twitter-integration-framework/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of the new feature that comes with iOS 5 is the native Twitter integration. You just have to register your account(s) in the Settings application and you are done, you can easily tweet your photos, links&#8230; with a nice looking interface. What&#8217;s even better for us developers, is that it&#8217;s really easy to take advantage of this feature.<br />
<span id="more-324"></span><br />
No more pain to integrate Twitter within your app. No more external source code that triggers tons of warnings when you are building, especially if, like me, you enable most of the warnings flags.<br />
Now all you need is to link with <strong>Twitter.framework</strong>, write a couple lines of code and you are done ! Of course if you intend to support older iOS version you have to weak link against the framework.</p>
<p>The few lines of code you need to write look like this :</p>
<pre class="brush: objc; title: ; notranslate">-(void)tweetAction
{
	Class twClass = NSClassFromString(@&quot;TWTweetComposeViewController&quot;);
	if (!twClass) // Framework not available, older iOS
		return;
	if ([TWTweetComposeViewController canSendTweet]) // Check if twitter is setup and reachable
	{
		TWTweetComposeViewController* twc = [[TWTweetComposeViewController alloc] init];
		[twc addURL:[NSURL URLWithString:@&quot;http://www.cocoabyss.com/&quot;]];
		[twc addImage:[UIImage imageNamed:@&quot;Some image.png&quot;]]
		[twc setInitialText:@&quot;iOS 5 Twitter tutorial&quot;];
		[_viewController presentViewController:twc animated:YES completion:^{
			// Optional
		}];
		// Assume twc is ARC released or call [twc release];
	}
	else
	{
		// Twitter account not configured, inform the user
	}
}
</pre>
<p><img src="http://www.cocoabyss.com/wp-content/uploads/2011/08/tw1.jpg" style="margin-left:auto;margin-right:auto;display:block; "/><br />
&bull; <i>You don&#8217;t need to shorten url(s), it will be done automatically by the framework.</i><br />
&bull; <i>You can add several images or URLs.</i></p>
<p>The <code>addImage:</code>, <code>addURL:</code> and <code>setInitialText:</code> methods return booleans values to indicate if the operations were successful. The reason of failure are :</p>
<p>&bull; <i>The Image / URL / Text doesn&#8217;t fit in the character space (> 140)</i><br />
&bull; <i>The view was presented to the user</i></p>
<p>And&#8230; that&#8217;s all there is to know ! Pretty neat no ? <img src='http://www.cocoabyss.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/misc/ios-5-twitter-integration-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Efficiently build a gallery like Photos.app</title>
		<link>http://www.cocoabyss.com/coding-practice/efficiently-build-a-gallery-like-photos-app/</link>
		<comments>http://www.cocoabyss.com/coding-practice/efficiently-build-a-gallery-like-photos-app/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 16:58:55 +0000</pubDate>
		<dc:creator>Nyx0uf</dc:creator>
				<category><![CDATA[Coding Practice]]></category>
		<category><![CDATA[UIKit]]></category>
		<category><![CDATA[gallery]]></category>
		<category><![CDATA[ImageIO]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[UIImage]]></category>
		<category><![CDATA[UIImageView]]></category>
		<category><![CDATA[UIScrollView]]></category>

		<guid isPermaLink="false">http://www.cocoabyss.com/?p=327</guid>
		<description><![CDATA[Quite often people wants to build a gallery like Photos.app for their iOS application. The exercise is really not difficult, but it&#8217;s also easy to kill your device memory if you don&#8217;t take the time to think of an elegant &#8230; <a href="http://www.cocoabyss.com/coding-practice/efficiently-build-a-gallery-like-photos-app/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Quite often people wants to build a gallery like <i>Photos.app</i> for their iOS application. The exercise is really not difficult, but it&#8217;s also easy to kill your device memory if you don&#8217;t take the time to think of an elegant way to do it.<br />
<span id="more-327"></span><br />
As I said, the concept is very easy, basically you just need to put some <code>UIImageView</code> inside a <code>UIScrollView</code> and you are done.<br />
But several times I saw code where people put as many UIImageView as they had images to display.</p>
<p><b><i>Bad idea. Why ?</i></b></p>
<p>Let&#8217;s say you have 13 images to display of the size of an iPhone screen (320*480).<br />
On iOS 1 pixel = 4bytes.<br />
So in memory, a single picture takes <strong>600Kb</strong>. Multiply this by 13 and you are at <strong>7.8Mb</strong> used.</p>
<p>And this, wasn&#8217;t the worst case scenario. Because often people doesn&#8217;t take the time to reduce their pictures to the size of the device and end up displaying, for example, 6 Mega Pixel image (<strong>That&#8217;s 24Mb in memory for a single image !</strong>) or even more, and that&#8217;s dramatic.</p>
<p><b><i>Good practices</i></b></p>
<p>Here the good practices are obvious.</p>
<p>&bull; <i>First, reduce your pictures size with, <a href="http://www.cocoabyss.com/coding-practice/uiimage-scaling-using-imageio/">for example</a>, ImageIO.</i><br />
&bull; <i>Then to build a gallery, 3 UIImageView are enough, really. One for the current displayed image, one for the previous and one for the next.</i></p>
<p>Knowing this, I&#8217;ll show you some simple code to illustrate this.</p>
<p>So first let&#8217;s create our view (I don&#8217;t use IB)</p>
<pre class="brush: objc; title: ; notranslate">-(void)loadView
{
	UIView* view = [[UIView alloc] initWithFrame:(CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = kPageWidth, .size.height = 320.0f}];

	UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:(CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = kPageWidth, .size.height = 320.0f}];
	scrollView.delegate = self;
	scrollView.backgroundColor = [UIColor blackColor];
	scrollView.showsVerticalScrollIndicator = NO;
	scrollView.showsHorizontalScrollIndicator = NO;
	scrollView.alwaysBounceVertical = NO;
	scrollView.alwaysBounceHorizontal = YES;
	scrollView.scrollsToTop = NO;
	scrollView.pagingEnabled = YES;
	scrollView.directionalLockEnabled = YES;
	scrollView.contentSize = (CGSize){.width = kPageWidth * _picturesCount, .height = 320.0f};
	scrollView.contentOffset = (CGPoint){.x = kPageWidth * _index, .y = 0.0f};
	[view addSubview:scrollView];

	_imageView1 = [[UIImageView alloc] initWithFrame:(CGRect){.origin.x = scrollView.contentOffset.x, .origin.y = 0.0f, .size.width = kPageWidth, .size.height = 320.0f}];
	_imageView1.tag = 1;
	[scrollView addSubview:_imageView1];

	_imageView2 = [[UIImageView alloc] initWithFrame:(CGRect){.origin.x = kPageWidth, .origin.y = 0.0f, .size.width = kPageWidth, .size.height = 320.0f}];
	_imageView2.tag = 2;
	[scrollView addSubview:_imageView2];

	_imageView3 = [[UIImageView alloc] initWithFrame:(CGRect){.origin.x = kPageWidth + kPageWidth, .origin.y = 0.0f, .size.width = kPageWidth, .size.height = 320.0f}];
	_imageView3.tag = 3;
	[scrollView addSubview:_imageView3];

	self.view = view;

	[scrollView release];
	[view release];
}</pre>
<p>– <strong>kPageWidth</strong> has a value of 480.0f.<br />
– <strong>_picturesCount</strong>, as the name implies, is an integer that represents the number of pictures (ivar).<br />
– <strong>_index</strong> is the index of the current displayed picture (ivar), starting at 0.</p>
<p>Then we need to implement the <code>-(void)scrollViewDidScroll:(UIScrollView*)scrollView</code> method.</p>
<pre class="brush: objc; title: ; notranslate">-(void)scrollViewDidScroll:(UIScrollView*)scrollView
{
	const CGFloat currPos = scrollView.contentOffset.x; // Get current X scrollview position
	const NSInteger selectedPage = lroundf(currPos * (1.0f / kPageWidth)); // Compute selected page
	const NSInteger zone = 1 + (selectedPage % 3); // Current zone : 0 - 1 - 2

	const NSInteger nextPage = selectedPage + 1;
	const NSInteger prevPage = selectedPage - 1;

	/// Next page
	if (nextPage &lt; (NSInteger)_picturesCount)
	{
		NSInteger nextViewTag = zone + 1;
		if (nextViewTag == 4)
			nextViewTag = 1;
		UIImageView* nextView = (UIImageView*)[scrollView viewWithTag:nextViewTag];
		nextView.frame = (CGRect){.origin.x = nextPage * kPageWidth, .origin.y = 0.0f, .size = nextView.frame.size};
		Picture* nextPic = [_pictures objectAtIndex:nextPage];
		UIImage* img = [[UIImage alloc] initWithContentsOfFile:nextPic.Path];
		nextView.image = img;
		[img release];
	}
	/// Prev page
	if (prevPage &gt;= 0)
	{
		NSInteger prevViewTag = zone - 1;
		if (!prevViewTag)
			prevViewTag = 3;
		UIImageView* prevView = (UIImageView*)[scrollView viewWithTag:prevViewTag];
		prevView.frame = (CGRect){.origin.x = prevPage * kPageWidth, .origin.y = 0.0f, .size = prevView.frame.size};
		Picture* prevPic = [_pictures objectAtIndex:prevPage];
		UIImage* img = [[UIImage alloc] initWithContentsOfFile:prevPic.Path];
		prevView.image = img;
		[img release];
	}

	if (_index != selectedPage &amp;&amp; selectedPage &gt;= 0 &amp;&amp; selectedPage &lt; _picturesCount)
	{
		Picture* currentPic = [_pictures objectAtIndex:selectedPage];
		self.navigationItem.title = currentPic.Title;
		_index = selectedPage;
	}
}</pre>
<p>– <strong>Picture</strong> is a class to encapsulate an image path, a title for the image and description.<br />
– I assume your images are already at the good size, you can find how to do this in the link I gave above.</p>
<p>That&#8217;s all the mechanisms for the gallery, after that it&#8217;s mainly UI customization.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cocoabyss.com/coding-practice/efficiently-build-a-gallery-like-photos-app/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

