美文网首页iOS开发攻城狮的集散地
UIImage与位图(RGBA8 Bitmaps)的相互转化

UIImage与位图(RGBA8 Bitmaps)的相互转化

作者: 王zuozuo | 来源:发表于2017-07-14 15:13 被阅读10次

    来自: http://paulsolt.com/2010/09/ios-converting-uiimage-to-rgba8-bitmaps-and-back/
    下载:https://github.com/PaulSolt/UIImage-Conversion

    使用方式

    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);
    

    ImageHelper.h

    #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

    #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
    

    相关文章

      网友评论

        本文标题:UIImage与位图(RGBA8 Bitmaps)的相互转化

        本文链接:https://www.haomeiwen.com/subject/ajtohxtx.html