2011-04-24 42 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();