Skip to content

Instantly share code, notes, and snippets.

@cookbrianj
Created June 4, 2012 20:44
Show Gist options
  • Save cookbrianj/2870762 to your computer and use it in GitHub Desktop.
Save cookbrianj/2870762 to your computer and use it in GitHub Desktop.
UIImage Category to help with IR photo processing tasks
//
// UIImage+IRHelpers.m
// RedStudio
//
// Created by Brian Cook on 6/4/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "UIImage+IRHelpers.h"
#import <Accelerate/Accelerate.h>
CGContextRef CreateARGBBitmapContext(const size_t width,
const size_t height,
const size_t bytesPerRow) {
CGContextRef bmContext = CGBitmapContextCreate(NULL,
width,
height,
8,
bytesPerRow,
CGColorSpaceCreateDeviceRGB(),
kCGBitmapByteOrderDefault |
kCGImageAlphaPremultipliedFirst);
return bmContext;
}
@implementation UIImage (IRHelpers)
- (UIImage *)swapRedAndBlueChannels {
CGImageRef image = self.CGImage;
size_t width = CGImageGetWidth(image);
size_t height = CGImageGetHeight(image);
size_t bytesPerRow = width * 4;
CGContextRef bmContext = CreateARGBBitmapContext(width, height, bytesPerRow);
CGContextDrawImage(bmContext, CGRectMake(0.0f, 0.0f, width, height), image);
UInt8* imageData = CGBitmapContextGetData(bmContext);
const size_t n = sizeof(unsigned char) * width * height * 4;
void *outBuffer = malloc(n);
vImage_Buffer src = {imageData, height, width, bytesPerRow};
vImage_Buffer dest = {outBuffer, height, width, bytesPerRow};
//ARGB to ABGR
const uint8_t map[4] = {0, 3, 2, 1};
vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags);
memcpy(imageData, outBuffer, n);
free(outBuffer);
CGImageRef result = CGBitmapContextCreateImage(bmContext);
UIImage *outImage = [UIImage imageWithCGImage:result];
CGContextRelease(bmContext);
CGImageRelease(result);
return outImage;
}
- (UIImage *)equalizeImage {
CGImageRef image = self.CGImage;
size_t width = CGImageGetWidth(image);
size_t height = CGImageGetHeight(image);
size_t bytesPerRow = width * 4;
CGContextRef bmContext = CreateARGBBitmapContext(width, height, bytesPerRow);
CGContextDrawImage(bmContext, CGRectMake(0.0f, 0.0f, width, height), image);
UInt8* imageData = CGBitmapContextGetData(bmContext);
const size_t n = sizeof(UInt8) * width * height * 4;
void *outBuffer = malloc(n);
vImage_Buffer src = {imageData, height, width, bytesPerRow};
vImage_Buffer dest = {outBuffer, height, width, bytesPerRow};
vImage_Error err = vImageEqualization_ARGB8888(&src, &dest, kvImageCopyInPlace);
if (err == kvImageNoError) {
memcpy(imageData, outBuffer, n);
}
free(outBuffer);
CGImageRef result = CGBitmapContextCreateImage(bmContext);
UIImage *outImage = [UIImage imageWithCGImage:result];
CGContextRelease(bmContext);
CGImageRelease(result);
return outImage;
}
- (UIImage *)stretchContrast {
CGImageRef image = self.CGImage;
size_t width = CGImageGetWidth(image);
size_t height = CGImageGetHeight(image);
size_t bytesPerRow = width * 4;
CGContextRef bmContext = CreateARGBBitmapContext(width, height, bytesPerRow);
CGContextDrawImage(bmContext, CGRectMake(0.0f, 0.0f, width, height), image);
UInt8* imageData = CGBitmapContextGetData(bmContext);
const size_t n = sizeof(UInt8) * width * height * 4;
void *outBuffer = malloc(n);
vImage_Buffer src = {imageData, height, width, bytesPerRow};
vImage_Buffer dest = {outBuffer, height, width, bytesPerRow};
vImage_Error err = vImageContrastStretch_ARGB8888(&src, &dest, kvImageCopyInPlace);
if (err == kvImageNoError) {
memcpy(imageData, outBuffer, n);
}
free(outBuffer);
CGImageRef result = CGBitmapContextCreateImage(bmContext);
UIImage *outImage = [UIImage imageWithCGImage:result];
CGContextRelease(bmContext);
CGImageRelease(result);
return outImage;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment