<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: ImageMagick on iPhone &#8211; Xcode</title>
	<atom:link href="http://www.cloudgoessocial.net/2009/07/09/imagemagick-on-iphone-xcode/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cloudgoessocial.net/2009/07/09/imagemagick-on-iphone-xcode/</link>
	<description>computer, travel, movies, music, cuisine and more</description>
	<lastBuildDate>Tue, 09 Mar 2010 04:55:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Cloud</title>
		<link>http://www.cloudgoessocial.net/2009/07/09/imagemagick-on-iphone-xcode/comment-page-1/#comment-130</link>
		<dc:creator>Cloud</dc:creator>
		<pubDate>Sun, 30 Aug 2009 11:17:55 +0000</pubDate>
		<guid isPermaLink="false">http://www.cloudgoessocial.net/?p=189#comment-130</guid>
		<description>Thank you for this great tip and for the supplied code. I&#039;ve added it to the project and referenced you as usual. Thanks again!</description>
		<content:encoded><![CDATA[<p>Thank you for this great tip and for the supplied code. I&#8217;ve added it to the project and referenced you as usual. Thanks again!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jon Kean</title>
		<link>http://www.cloudgoessocial.net/2009/07/09/imagemagick-on-iphone-xcode/comment-page-1/#comment-125</link>
		<dc:creator>Jon Kean</dc:creator>
		<pubDate>Wed, 26 Aug 2009 20:48:40 +0000</pubDate>
		<guid isPermaLink="false">http://www.cloudgoessocial.net/?p=189#comment-125</guid>
		<description>the code for pulling in UIImages directly (without compression) doesn&#039;t work for images with an unusual number of bits per component (such as 5-bit components).

Since ImageMagick doesn&#039;t support components with arbitrary bit depth (only 8/16/32/etc), the simplest solution is to convert the UIImage into a consistent format before processing with ImageMagick.

Here is something to do just that (also fixed a leaking data provider):

[code lang=&quot;cpp&quot;]
CGImageRef createStandardImage(CGImageRef image) {
	const size_t width = CGImageGetWidth(image);
	const size_t height = CGImageGetHeight(image);
	CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
	CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, 8, 4*width, space,
											 kCGBitmapByteOrder32Big &#124; kCGImageAlphaPremultipliedFirst);
	CGColorSpaceRelease(space);
	CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), image);
	CGImageRef dstImage = CGBitmapContextCreateImage(ctx);
	CGContextRelease(ctx);
	return dstImage;
}

- (UIImage*) createPosterizeImage:(CGImageRef)srcCGImage {
	const unsigned long width = CGImageGetWidth(srcCGImage);
	const unsigned long height = CGImageGetHeight(srcCGImage);

	// could use the image directly if it has 8/16 bits per component,
	// otherwise the image must be converted into something more common (such as images with 5-bits per component)
	// here we&#039;ll be simple and always convert 
	const char *map = &quot;ARGB&quot;; // hard coded
	const StorageType inputStorage = CharPixel;
	CGImageRef standardized = createStandardImage(srcCGImage);
	NSData *srcData = (NSData *) CGDataProviderCopyData(CGImageGetDataProvider(standardized));
	CGImageRelease(standardized);
	
	const void *bytes = [srcData bytes];
	MagickWandGenesis();
	MagickWand *magick_wand = NewMagickWand();
	
	MagickBooleanType status = MagickConstituteImage(magick_wand, width, height, map, inputStorage, bytes);
	if (status == MagickFalse) {
		ThrowWandException(magick_wand);
	}
	
	status = MagickOrderedPosterizeImage(magick_wand, &quot;h8x8o&quot;);
	if (status == MagickFalse) {
		ThrowWandException(magick_wand);
	}
	
	const int bitmapBytesPerRow = (width * strlen(map));
	const int bitmapByteCount = (bitmapBytesPerRow * height);
	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
	char *trgt_image = malloc(bitmapByteCount);
	status = MagickExportImagePixels(magick_wand, 0, 0, width, height, map, CharPixel, trgt_image);
	if (status == MagickFalse) {
		ThrowWandException(magick_wand);
	}
	
	magick_wand = DestroyMagickWand(magick_wand);
	MagickWandTerminus();
	
	CGContextRef context = CGBitmapContextCreate (trgt_image,
												  width,
												  height,
												  8, // bits per component
												  bitmapBytesPerRow,
												  colorSpace,
												  kCGImageAlphaPremultipliedFirst);
	CGColorSpaceRelease(colorSpace);
	
	CGImageRef cgimage = CGBitmapContextCreateImage(context);
	UIImage *image = [[UIImage alloc] initWithCGImage:cgimage];
	CGImageRelease(cgimage);
	CGContextRelease(context);
	[srcData release];
	free(trgt_image);
	
	return image;
}
[/code]</description>
		<content:encoded><![CDATA[<p>the code for pulling in UIImages directly (without compression) doesn&#8217;t work for images with an unusual number of bits per component (such as 5-bit components).</p>
<p>Since ImageMagick doesn&#8217;t support components with arbitrary bit depth (only 8/16/32/etc), the simplest solution is to convert the UIImage into a consistent format before processing with ImageMagick.</p>
<p>Here is something to do just that (also fixed a leaking data provider):</p>
<pre class="brush: cpp;">
CGImageRef createStandardImage(CGImageRef image) {
	const size_t width = CGImageGetWidth(image);
	const size_t height = CGImageGetHeight(image);
	CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
	CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, 8, 4*width, space,
											 kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedFirst);
	CGColorSpaceRelease(space);
	CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), image);
	CGImageRef dstImage = CGBitmapContextCreateImage(ctx);
	CGContextRelease(ctx);
	return dstImage;
}

- (UIImage*) createPosterizeImage:(CGImageRef)srcCGImage {
	const unsigned long width = CGImageGetWidth(srcCGImage);
	const unsigned long height = CGImageGetHeight(srcCGImage);

	// could use the image directly if it has 8/16 bits per component,
	// otherwise the image must be converted into something more common (such as images with 5-bits per component)
	// here we'll be simple and always convert
	const char *map = "ARGB"; // hard coded
	const StorageType inputStorage = CharPixel;
	CGImageRef standardized = createStandardImage(srcCGImage);
	NSData *srcData = (NSData *) CGDataProviderCopyData(CGImageGetDataProvider(standardized));
	CGImageRelease(standardized);

	const void *bytes = [srcData bytes];
	MagickWandGenesis();
	MagickWand *magick_wand = NewMagickWand();

	MagickBooleanType status = MagickConstituteImage(magick_wand, width, height, map, inputStorage, bytes);
	if (status == MagickFalse) {
		ThrowWandException(magick_wand);
	}

	status = MagickOrderedPosterizeImage(magick_wand, "h8x8o");
	if (status == MagickFalse) {
		ThrowWandException(magick_wand);
	}

	const int bitmapBytesPerRow = (width * strlen(map));
	const int bitmapByteCount = (bitmapBytesPerRow * height);
	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
	char *trgt_image = malloc(bitmapByteCount);
	status = MagickExportImagePixels(magick_wand, 0, 0, width, height, map, CharPixel, trgt_image);
	if (status == MagickFalse) {
		ThrowWandException(magick_wand);
	}

	magick_wand = DestroyMagickWand(magick_wand);
	MagickWandTerminus();

	CGContextRef context = CGBitmapContextCreate (trgt_image,
												  width,
												  height,
												  8, // bits per component
												  bitmapBytesPerRow,
												  colorSpace,
												  kCGImageAlphaPremultipliedFirst);
	CGColorSpaceRelease(colorSpace);

	CGImageRef cgimage = CGBitmapContextCreateImage(context);
	UIImage *image = [[UIImage alloc] initWithCGImage:cgimage];
	CGImageRelease(cgimage);
	CGContextRelease(context);
	[srcData release];
	free(trgt_image);

	return image;
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: sachin</title>
		<link>http://www.cloudgoessocial.net/2009/07/09/imagemagick-on-iphone-xcode/comment-page-1/#comment-77</link>
		<dc:creator>sachin</dc:creator>
		<pubDate>Sat, 25 Jul 2009 19:59:42 +0000</pubDate>
		<guid isPermaLink="false">http://www.cloudgoessocial.net/?p=189#comment-77</guid>
		<description>hi cloud 

thanks a lot for guidance 
how can i store UIImage into custom location and process the file using ImageMagick.</description>
		<content:encoded><![CDATA[<p>hi cloud </p>
<p>thanks a lot for guidance<br />
how can i store UIImage into custom location and process the file using ImageMagick.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Karl</title>
		<link>http://www.cloudgoessocial.net/2009/07/09/imagemagick-on-iphone-xcode/comment-page-1/#comment-65</link>
		<dc:creator>Karl</dc:creator>
		<pubDate>Mon, 13 Jul 2009 19:39:46 +0000</pubDate>
		<guid isPermaLink="false">http://www.cloudgoessocial.net/?p=189#comment-65</guid>
		<description>Brilliant. It&#039;s also short on any releasing probably :-)</description>
		<content:encoded><![CDATA[<p>Brilliant. It&#8217;s also short on any releasing probably :-)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Cloud</title>
		<link>http://www.cloudgoessocial.net/2009/07/09/imagemagick-on-iphone-xcode/comment-page-1/#comment-64</link>
		<dc:creator>Cloud</dc:creator>
		<pubDate>Mon, 13 Jul 2009 12:46:34 +0000</pubDate>
		<guid isPermaLink="false">http://www.cloudgoessocial.net/?p=189#comment-64</guid>
		<description>@Karl: amazing job. I will put it into the XCode project for everyone to look at it in a &#039;better formatted&#039; way. I will also look into some benchmarking! :)</description>
		<content:encoded><![CDATA[<p>@Karl: amazing job. I will put it into the XCode project for everyone to look at it in a &#8216;better formatted&#8217; way. I will also look into some benchmarking! :)</p>
]]></content:encoded>
	</item>
</channel>
</rss>
