569Layering one UIImage onto of another UIImage

Combining two images, especially useful, if the overlay image has an alpha value:
//  UIImage+Category.h
//  ImageOverlay
//  Created by Georg Tremmel on 29/04/2010.


@interface UIImage (combine)

- (UIImage*)overlayWith:(UIImage*)overlayImage;

And the implementation file.
//  UIImage+Category.m
//  ImageOverlay
//  Created by Georg Tremmel on 29/04/2010.

#import "UIImage+Category.h"

@implementation UIImage (combine)

- (UIImage*)overlayWith:(UIImage*)overlayImage {
	// size is taken from the background image
	[self drawAtPoint:CGPointZero];
	[overlayImage drawAtPoint:CGPointZero];
	// If Image Artifacts appear, replace the "overlayImage drawAtPoint" , method with the following
	// Yes, it's a workaround, yes I filed a bug report
	CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height);
	[overlayImage drawInRect:imageRect blendMode:kCGBlendModeOverlay alpha:0.999999999];
	UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext();
	return combinedImage;


An update to 334 Combining Images with UIImage & CGContext – (Offscreen drawing) (Did I say, how much I love Categories…?) Update I came across some strange behaviour when layering a PNG image with transparency over another image. Did not show up in the Simulator, only in iPhone 3GS (and probably also on other devices.) The base image draws fine, but the overlay image appears to be truncated and the last pixels shifted, producing some bright green artifacts. Changing
[overlayImage drawAtPoint:CGPointZero];
CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height);
[overlayImage drawInRect:imageRect blendMode:kCGBlendModeOverlay alpha:1.0];
did not really help; the green artifacts remainded. It was strange though, that they did not appear in the other blendmodes. Using
CGContextDrawImage(c, imageRect, [overlayImage CGImage]);
would also work, but then the images turn up upside down. Not what I really needed. (Yes, I know, there might not be a hard fix for that, but really – it should be that complicated.) After playing a bit more with the values, I found, that setting alpha lower than 1.0 gets rid of the display artifact:
[overlayImage drawInRect:imageRect blendMode:kCGBlendModeOverlay alpha:0.9999999];
Bug filed at Apple’s Bug Report, let’s see. Or maybe am I missing something here? Anyway here they the files are, zipped and ready for download. Post Scriptum Test Project, showing the visual artifact in action. Only appears on the device, NOT IN THE SIMULATOR.

361Transparent Background of Custom Drawing Class

Usually common problems already have simple solution. Like that one: Problem You subclassed UIView, you want to do some custom drawing in drawRect, but no matter what you do or where you draw, the background of the view remains black.
- (void)drawRect:(CGRect)rect {
 // Drawing code
 CGContextRef context = UIGraphicsGetCurrentContext();
 CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
 CGContextFillEllipseInRect(context, rect);
Solution In the ViewController, which call the drawing class, add
myDrawingClass.opaque = NO;
– or even nicer. In the drawing class’ init function:
self.opaque = NO;
And not like that – adding “self.opaque = NO;” in the drawRect: function – CGContextClearRect(context, rect); – CGContextSetAlpha(context, 0.5f);

338Accessing RGBA Pixel Data

NSData* pixelData = (NSData*) 
unsigned char* pixelBytes = (unsigned char *)[pixelData bytes];
for(int i = 0; i < [pixelData length]; i += 4) {
		NSLog(@"pixelBytes[i] R:%i G:%i B:%i A:%i ", 
		pixelBytes[i] = pixelBytes[i+3];
		pixelBytes[i+1] = pixelBytes[i+3];
		pixelBytes[i+2] = pixelBytes[i+3];
		pixelBytes[i+3] = 0;
	NSData* newPixelData = [NSData dataWithBytes:pixelBytes length:[pixelData length]];
	UIImage* newImage = [UIImage imageWithData:newPixelData];

128Adding Alpha Blending Mode to Quartz Composer

Courtesy of Kineme. http://kineme.net/QuartzComposerPatches/GLTools/1.1