2011-04-24 38 views
10

我有以下问题,只能部分解决它。我正在使用XCode 3.2.5,为iOS 4+开发。如何创建空白/空白UIImage或CGImage并操作其上的像素(Xcode)?

我只是尝试创建一个预定义大小的图像,操纵它上的像素,然后在UIImageView中显示图像。我的视图由简单的按钮连接到和IBAction称为“buttonClicked”和UIImageView称为“qrImage”并被设置为“IBOutlet”。我用下面的代码:

页眉文件:myClassViewController.h

#import <UIKit/UIKit.h> 

@interface myClassViewController : UIViewController 
{ 
    IBOutlet UIImageView *qrImage; 
} 

@property (nonatomic, retain) UIImageView *qrImage; 

- (IBAction) buttonClicked; 
- (UIImage*) drawQRImage; 

@end 

主文件myClassViewController.m

#import "myClassViewController.h" 
#include <math.h> 

@implementation myClassViewController 
@synthesize qrImage; 


-(UIImage*) drawQRImage 
{ 
    // load Image 
    // 
    UIImage *image    = [UIImage imageNamed:@"blank.png"];  
    CGImageRef imageRef   = image.CGImage; 
    NSData *data    = (NSData *) CGDataProviderCopyData(CGImageGetDataProvider(imageRef)); 
    char *pixels    = (char *)[data bytes]; 

    unsigned long int startPixel, pixelNr; 


    // manipulate the individual pixels 
    // 
    size_t width    = CGImageGetWidth(imageRef); 
    size_t height    = CGImageGetHeight(imageRef); 

    // 
    // [...] deleted some unimportant code here 
    // 

    pixelNr = 10; 

    int red     = pixelNr*3; 
    int green    = pixelNr*3+1; 
    int blue    = pixelNr*3+2; 

    // Set Pixel-Color Black 
    // 
    pixels[red]   = 0; 
    pixels[green]   = 0; 
    pixels[blue]   = 0; 

    // 
    // [...] deleted some unimportant code here 
    // 

    // create a new image from the modified pixel data 
    // 
    size_t bitsPerComponent  = CGImageGetBitsPerComponent(imageRef); 
    size_t bitsPerPixel   = CGImageGetBitsPerPixel(imageRef); 
    size_t bytesPerRow   = CGImageGetBytesPerRow(imageRef); 

    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); 
    CGBitmapInfo bitmapInfo  = CGImageGetBitmapInfo(imageRef); 
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, [data length], NULL); 

    CGImageRef newImageRef  = CGImageCreate (
               width, 
               height, 
               bitsPerComponent, 
               bitsPerPixel, 
               bytesPerRow, 
               colorspace, 
               bitmapInfo, 
               provider, 
               NULL, 
               false, 
               kCGRenderingIntentDefault 
               ); 

    // the modified image 
    // 
    UIImage *newImage   = [UIImage imageWithCGImage:newImageRef]; 

    // cleanup 
    // 
    free(pixels); 
    //CGImageRelease(imageRef); // DO NOT RELEASE OR ON NEXT RUN NSData GETS EXC_BAD_ACCESS 
    CGColorSpaceRelease(colorspace); 
    CGDataProviderRelease(provider); 
    CGImageRelease(newImageRef); 

    QRcode_free(qrCode); 
    QRinput_free(input); 

    [image release]; 

    // return created Image 
    // 
    return newImage; 
} 


-(IBAction) buttonClicked 
{ 
    UIImage *createdUIImg = [self drawQRImage]; 
    qrImage.image = createdUIImg; 
} 

我希望的代码是相当自我解释,如果不是在这里短描述:

A.按钮 - 点击我调用方法drawQRImage,它将返回一个UIImage。 B. drawQRImage内部我打开一个PNG文件,直到现在它的大小为210x210,只有一个白色的背景。没有其他的。然后我操纵一些像素,并将它们涂成黑色。当前的代码应该设置像素nr。 11黑。完成后,我将返回新创建的图像。 C:buttonClicked方法将在UIImageView中显示这个图像。

总而言之其实很简单。它也可以(几乎)完美地工作。但现在我想作一些修改,但不能让他们一直工作到现在:

  1. 我不得不返回图像并不总是210x210像素,所以我必须能够改变大小。加载一个“空白”的PNG文件,并操纵它的像素是唯一的解决方法,直到现在我设法得到工作。一种更优雅的方式是创建一个空白的图像,并使用我现有方法中可以使用的所需大小的白色BG。不幸的是我还没有找到关于这个主题的任何内容。只能操作已存在的全部图像上的像素。这就是我提出目前的解决方法。我已经尝试从以下链接剪下调整大小:Resizing a UIImage the right way

  2. 该按钮可以被点击几次,画的像素也会改变。我现在的问题是,我似乎有内存泄漏,因为我注释了行

    // CGImageRelease(imageRef);

但是如果我去做释放UIImageRef“imageRef”,我将再次点击该按钮时,得到一个EXC_BAD_ACCESS错误。所以我知道这意味着我尝试访问一个已经发布的对象。但是我怎么能解决这个问题,我不知道我是否能够在这里得到一切。我认为imageRef将在方法“drawQRImage”开始时新创建,因此当我再次调用方法时释放它不应该成为问题。但看起来我似乎错了。

每一位的帮助表示赞赏!

+0

我发现了一个并不完美,但更多或更少的可接受的解决方法#1的问题。我会在测试完成后立即发布代码。不过,如果有人能够给我一个关于如何创建一个空白图像的提示,而不是必须打开一个空白/白色PNG(我现在这样做),我会很高兴。 关于问题#2:我想下面的链接回答我的问题到我的EXC_BAD_ACCESS-错误,对吧? http://stackoverflow.com/questions/1428102/does-cgimagerelease-free-uiimages-memory – EliteTUM 2011-04-29 11:32:51

回答

4

下面的讨论地址的内存管理CGImage对象: Releasing CGImage (CGImageRef)

为空白图像问题: Drawing into CGImageRef

+0

前段时间我问了这个问题,不过谢谢。我想这会做到!这两个链接看起来很有前途不得不暂停该项目,但将继续在12月左右开展工作。 – EliteTUM 2011-08-27 07:55:32

3

为什么不这样简单的一招?这个对我有用。 (假定self.imageViewSymbolUIImageView*

self.imageViewSymbol.image = nil; 
self.imageView.frame = CGRect(...as you like...); 
UIGraphicsBeginImageContext(self.imageViewSymbol.bounds.size); 
[self.imageViewSymbol.image drawInRect:self.imageViewSymbol.bounds]; 
self.imageViewSymbol.image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
1

大厦大小和规模来创建图像

UIGraphicsBeginImageContextWithOptions(*defineSize*, NO, *Scale*); 
UIImage *imgClearBG = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext();