UIImage与位图(RGBA8 Bitmaps)的相互转化
来自 http://paulsolt.com/2010/09/ios-converting-uiimage-to-rgba8-bitmaps-and-back/
下载:https://github.com/PaulSolt/UIImage-Conversion
ImageHelper.h
/* * The MIT License * * Copyright (c) 2011 Paul Solt, PaulSolt@gmail.com * * https://github.com/PaulSolt/UIImage-Conversion/blob/master/MITLicense.txt * */
#import <Foundation/Foundation.h>
@interface ImageHelper : NSObject {
}
/** Converts a UIImage to RGBA8 bitmap. @param image - a UIImage to be converted @return a RGBA8 bitmap, or NULL if any memory allocation issues. Cleanup memory with free() when done. */+ (unsigned char *) convertUIImageToBitmapRGBA8:(UIImage *)image;
/** A helper routine used to convert a RGBA8 to UIImage @return a new context that is owned by the caller */+ (CGContextRef) newBitmapRGBA8ContextFromImage:(CGImageRef)image;
/** Converts a RGBA8 bitmap to a UIImage. @param buffer - the RGBA8 unsigned char * bitmap @param width - the number of pixels wide @param height - the number of pixels tall @return a UIImage that is autoreleased or nil if memory allocation issues */+ (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *)buffer withWidth:(int)width withHeight:(int)height;
@end
ImageHelper.m/* * The MIT License * * Copyright (c) 2011 Paul Solt, PaulSolt@gmail.com * * https://github.com/PaulSolt/UIImage-Conversion/blob/master/MITLicense.txt * */
#import "ImageHelper.h"
@implementation ImageHelper
+ (unsigned char *) convertUIImageToBitmapRGBA8:(UIImage *) image {
CGImageRef imageRef = image.CGImage;
// Create a bitmap context to draw the uiimage into CGContextRef context = [self newBitmapRGBA8ContextFromImage:imageRef];
if(!context) { return NULL; }
size_t width = CGImageGetWidth(imageRef); size_t height = CGImageGetHeight(imageRef);
CGRect rect = CGRectMake(0, 0, width, height);
// Draw image into the context to get the raw image data CGContextDrawImage(context, rect, imageRef);
// Get a pointer to the data unsigned char *bitmapData = (unsigned char *)CGBitmapContextGetData(context);
// Copy the data and release the memory (return memory allocated with new) size_t bytesPerRow = CGBitmapContextGetBytesPerRow(context); size_t bufferLength = bytesPerRow * height;
unsigned char *newBitmap = NULL;
if(bitmapData) { newBitmap = (unsigned char *)malloc(sizeof(unsigned char) * bytesPerRow * height);
if(newBitmap) { // Copy the data for(int i = 0; i < bufferLength; ++i) { newBitmap[i] = bitmapData[i]; } }
free(bitmapData);
} else { NSLog(@"Error getting bitmap pixel data\n"); }
CGContextRelease(context);
return newBitmap; }
+ (CGContextRef) newBitmapRGBA8ContextFromImage:(CGImageRef) image { CGContextRef context = NULL; CGColorSpaceRef colorSpace; uint32_t *bitmapData;
size_t bitsPerPixel = 32; size_t bitsPerComponent = 8; size_t bytesPerPixel = bitsPerPixel / bitsPerComponent;
size_t width = CGImageGetWidth(image); size_t height = CGImageGetHeight(image);
size_t bytesPerRow = width * bytesPerPixel; size_t bufferLength = bytesPerRow * height;
colorSpace = CGColorSpaceCreateDeviceRGB();
if(!colorSpace) { NSLog(@"Error allocating color space RGB\n"); return NULL; }
// Allocate memory for image data bitmapData = (uint32_t *)malloc(bufferLength);
if(!bitmapData) { NSLog(@"Error allocating memory for bitmap\n"); CGColorSpaceRelease(colorSpace); return NULL; }
//Create bitmap context
context = CGBitmapContextCreate(bitmapData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); // RGBA if(!context) { free(bitmapData); NSLog(@"Bitmap context not created"); }
CGColorSpaceRelease(colorSpace);
return context; }
+ (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *) buffer withWidth:(int) width withHeight:(int) height {
size_t bufferLength = width * height * 4; CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL); size_t bitsPerComponent = 8; size_t bitsPerPixel = 32; size_t bytesPerRow = 4 * width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); if(colorSpaceRef == NULL) { NSLog(@"Error allocating color space"); CGDataProviderRelease(provider); return nil; }
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, // data provider NULL, // decode YES, // should interpolate renderingIntent);
uint32_t* pixels = (uint32_t*)malloc(bufferLength);
if(pixels == NULL) { NSLog(@"Error: Memory not allocated for bitmap"); CGDataProviderRelease(provider); CGColorSpaceRelease(colorSpaceRef); CGImageRelease(iref); return nil; }
CGContextRef context = CGBitmapContextCreate(pixels, width, height, bitsPerComponent, bytesPerRow, colorSpaceRef, kCGImageAlphaPremultipliedLast);
if(context == NULL) { NSLog(@"Error context not created"); free(pixels); }
UIImage *image = nil; if(context) {
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
// Support both iPad 3.2 and iPhone 4 Retina displays with the correct scale if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) { float scale = [[UIScreen mainScreen] scale]; image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp]; } else { image = [UIImage imageWithCGImage:imageRef]; }
CGImageRelease(imageRef); CGContextRelease(context); }
CGColorSpaceRelease(colorSpaceRef); CGImageRelease(iref); CGDataProviderRelease(provider);
if(pixels) { free(pixels); } return image;}
@end
这样使用NSString *path = (NSString*)[[NSBundle mainBundle] pathForResource:@"Icon4" ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:path];
int width = image.size.width;
int height = image.size.height;
// Create a bitmap
unsigned char *bitmap = [ImageHelper convertUIImageToBitmapRGBA8:image];
// Create a UIImage using the bitmap
UIImage *imageCopy = [ImageHelper convertBitmapRGBA8ToUIImage:bitmap withWidth:width withHeight:height];
// Display the image copy on the GUI
UIImageView *imageView = [[UIImageView alloc] initWithImage:imageCopy];
// Cleanup
free(bitmap);