Skip to content

Instantly share code, notes, and snippets.

@jagbolanos
Created September 10, 2012 23:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jagbolanos/3694862 to your computer and use it in GitHub Desktop.
Save jagbolanos/3694862 to your computer and use it in GitHub Desktop.
Apply an overlay to an image that has alpha only on the visible parts
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
#import <stdlib.h>
- (CGImageRef) createMaskWithImageAlpha: (CGContextRef) originalImageContext {
UInt8 *data = (UInt8 *)CGBitmapContextGetData(originalImageContext);
float width = CGBitmapContextGetBytesPerRow(originalImageContext) / 4;
float height = CGBitmapContextGetHeight(originalImageContext);
// Make a bitmap context that's only 1 alpha channel
// WARNING: the bytes per row probably needs to be a multiple of 4
int strideLength = ROUND_UP(width * 1, 4);
unsigned char * alphaData = (unsigned char * )calloc(strideLength * height, 1);
CGContextRef alphaOnlyContext = CGBitmapContextCreate(alphaData,
width,
height,
8,
strideLength,
NULL,
kCGImageAlphaOnly);
// Draw the RGBA image into the alpha-only context.
//CGContextDrawImage(alphaOnlyContext, CGRectMake(0, 0, width, height), originalMaskImage);
// Walk the pixels and invert the alpha value. This lets you colorize the opaque shapes in the original image.
// If you want to do a traditional mask (where the opaque values block) just get rid of these loops.
unsigned int zeros = 0, ones = 0, other=0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
//unsigned char val = alphaData[y*strideLength + x];
unsigned char val = data[y*(int)width*4 + x*4 + 3];
if (val == 0) zeros++;
else if (val == 255) ones++;
else other++;
val = 255 - val;
alphaData[y*strideLength + x] = val;
}
}
CGImageRef alphaMaskImage = CGBitmapContextCreateImage(alphaOnlyContext);
CGContextRelease(alphaOnlyContext);
free(alphaData);
// Make a mask
CGImageRef finalMaskImage = CGImageMaskCreate(CGImageGetWidth(alphaMaskImage),
CGImageGetHeight(alphaMaskImage),
CGImageGetBitsPerComponent(alphaMaskImage),
CGImageGetBitsPerPixel(alphaMaskImage),
CGImageGetBytesPerRow(alphaMaskImage),
CGImageGetDataProvider(alphaMaskImage), NULL, false);
CGImageRelease(alphaMaskImage);
return finalMaskImage;
}
-(UIImage *)greenImage: (UIImage *)image{
CGImageRef originalImage = [image CGImage];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIImage *maskImage = [UIImage imageNamed:@"filteroverlay_80percent.jpg"];
CGImageRef maskImageRef = [maskImage CGImage];
CGContextRef bitmapContext = CGBitmapContextCreate(NULL,
CGImageGetWidth(originalImage),
CGImageGetHeight(originalImage),
8,
CGImageGetWidth(originalImage)*4,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(bitmapContext, CGRectMake(0, 0, CGBitmapContextGetWidth(bitmapContext), CGBitmapContextGetHeight(bitmapContext)), originalImage);
CGImageRef finalMaskImage = [self createMaskWithImageAlpha:bitmapContext];
CGContextSetBlendMode(bitmapContext, kCGBlendModeOverlay);
CGContextSetAlpha(bitmapContext, 0.8f);
CGImageRef maskedOverlay = CGImageCreateWithMask(maskImageRef, finalMaskImage);
CGContextDrawImage(bitmapContext, CGRectMake(0, 0, CGBitmapContextGetWidth(bitmapContext), CGBitmapContextGetHeight(bitmapContext)), maskedOverlay);
CGImageRef outImage = CGBitmapContextCreateImage(bitmapContext);
UIImage *retImage = [UIImage imageWithCGImage:outImage];
CGImageRelease(outImage);
CGContextRelease(bitmapContext);
CGImageRelease(finalMaskImage);
CGImageRelease(maskedOverlay);
return retImage;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment