1

古い 1 ピクセルからピクセルごとに新しい UIImage を生成するイメージ フィルタをプログラムしました。私の画像を含むクラスでは、宣言は次のとおりです。

@property   UIImage *imageHandle;       // contains the image of the class

CBImage クラスのフィルターは、UIImage からビットマップを char 配列 (ピクセル) として抽出し、同じサイズの新しい char 配列バッファー (newPixels) を割り当ててから、RGBA ピクセルを実行して、フィルター処理された画像を newPixels に再構築します。最後に、新しい UIImage を生成し、これを返します。

これはコードです(CBImageは上記の宣言を含む私のクラスです):

-(CBImage *)doMyFancyStuff
{
// set up some convenience variables
UIImage *image = self.imageHandle;
CGImageRef imageRef = image.CGImage;
NSData *imageData = (NSData *)CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef)));
NSLog(@"NumPixels %d", [imageData length]);
char *pixels = (char *)[imageData bytes];

char *newPixels = (char *)calloc([imageData length], sizeof(char));

// run through the image and manipulate the image
for (NSInteger i=0; i< [imageData length]; i+=4)
{
    if ([whatEverIWantIsTrueForMyFilter])
    {
        // color pixel white and ALPHA = 1.0
        newPixels[i] = 255;
        newPixels[i+1] = 255;
        newPixels[i+2] = 255;
        newPixels[i+3] = 255;
    }
    else
        newPixels[i+3] = 0;  // make pixel translucent
}

// create new image
CBImage *result = [[CBImage alloc] init];

// construct new UImage 
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
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, newPixels, [imageData length], NULL);

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

result.imageHandle = [UIImage imageWithCGImage:newImageRef];

// clean up
free(pixels);
free(newPixels);
CGImageRelease(imageRef);
CGColorSpaceRelease(colorspace);
CGDataProviderRelease(provider);
CGImageRelease(newImageRef);
newImageRef = Nil;

return result;

}

これらはすべてうまく機能しているようで、新しく作成した UImage をビュー コントローラーに表示できます。

CBImage *overlayImage = [testCBImage doMyFancyStuff];
self.overlayView.image = overlayImage.imageHandle;

しかし...イメージを再度解放したい場合は、BAD_ACCESS例外がスローされます。

self.overlayView.image = Nil;

ここで何が問題なのかわかりません。私が持っている唯一の疑いは、上記のフィルタ メソッドの 10 行目の calloc 呼び出しです。 UIImageハンドルはNilに設定されています...しかし、よくわかりません。

iOS7とARCを使用しています。

何か案は?

ベスキ

4

1 に答える 1

3
char *pixels = (char *)[imageData bytes];

そして、後で...

free(pixels);

ただし、ピクセルは create / malloc / ... などを使用して作成されていないため、解放する必要はありません。

また、プロパティを保持(または強力な同じもの)で宣言することを検討してください。

@property (nonatomic, retain)UIImage *imageHandle;       // contains the image of the class
于 2013-11-12T20:35:42.087 に答える