0

複数の効果を画像に適用しようとしています。UIImageViewに送信して変更されたコピーを受信できるエフェクト処理を処理する別のファイルを作成しました。処理時間を節約するために、画像を変更するたびに画像を読み込むのではなく、まず画像を別の処理ファイルに読み込んでメモリに保存します。getImageData -> modifyRGB -> displayImage の流れです。すべてが最後のステップまで機能します。返された変更された画像が一瞬画面に表示され、Xcode がEXEC_BAD_ACCESS:code 1 エラーでクラッシュします。コードを繰り返し調べましたが、問題が見つかりません。どんな助けでも大歓迎です。ありがとうございました!

詳細情報を更新

自動参照カウントでXcode 4.3.1を使用しています

改行を使用すると、 self.imageView.image = [self.imageManipulation displayImage];という行でクラッシュが発生することを確認できます。実行されます。イメージは更新されますが、プログラムはすぐにクラッシュします。NSZombie を使用すると、エラーが発生します-[Not A Type preserve]: message sent to deallocated instance 0x2cceaf80

私のviewControllerから私は使用します:

[self.imageManipulation getImageData:self.imageView.image];
[self.imageManipulation modifyRGB];
self.imageView.image = [self.imageManipulation displayImage];

私の ImageManipulation ファイルは次のもので構成されています。

@implementation ImageManipulation
static unsigned char *rgbaDataOld;
static unsigned char *rgbaDataNew;
static int width;
static int height;

- (void)getImageData:(UIImage *)image
{
    CGImageRef imageRef = [image CGImage];

    width = CGImageGetWidth(imageRef);
    height = CGImageGetHeight(imageRef);

    rgbaDataOld = malloc(height * width * 4);
    rgbaDataNew = malloc(height * width * 4);

    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = CGBitmapContextCreate(rgbaDataOld, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);

    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    CGImageRelease(imageRef);
}

//modify rgb values 
- (void)modifyRGB
{
    for (int byteIndex = 0 ; byteIndex < width * height * 4; byteIndex += 4)
    {
        rgbaDataNew[byteIndex] = (char) (int) (rgbaDataOld[byteIndex] / 3) + 1;
        rgbaDataNew[byteIndex+1] = (char) (int) (rgbaDataOld[byteIndex+1] / 3 + 1);
        rgbaDataNew[byteIndex+2] = (char) (int) (rgbaDataOld[byteIndex+2] / 3) + 1;
        rgbaDataNew[byteIndex+3] = (char) (int) 255;
    }    
}

//set image
- (UIImage *)displayImage
{
    CGContextRef context;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    context = CGBitmapContextCreate(rgbaDataNew, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast ); 

    CGImageRef imageRef = CGBitmapContextCreateImage (context);
    UIImage *outputImage = [UIImage imageWithCGImage:imageRef];  

    CGColorSpaceRelease(colorSpace);    
    CGContextRelease(context);  
    CGImageRelease(imageRef);
    return outputImage;
}

@end
4

3 に答える 3

1

UIImageViewプロパティを受け取り、 VOIDを返すようにdispayImage()メソッドを変更しました。このように、ローカライズされたインスタンスではなく、渡されたUIImageViewに対してすべての作業が行われ、何も返されません。

私の推測では、メソッドが完了した 2 番目に返された参照が割り当て解除されたため、以前に使用していた返されたUIImageアプローチがクラッシュしていたのです。これにより、悪影響を与えることなくCGImageReleaseを使用することもできます。

新しいアプローチは次のとおりです。

- (void)displayImage:(UIImageView *)image
{
   CGContextRef context;
   CGImageRef imageRef = [image.image CGImage];

   CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
   context = CGBitmapContextCreate(rgbaDataNew, width, height, 8, 4 * width, colorSpace,  kCGImageAlphaPremultipliedLast ); 
   imageRef = CGBitmapContextCreateImage (context);
   image.image = [UIImage imageWithCGImage:imageRef];
   CGColorSpaceRelease(colorSpace);    
   CGContextRelease(context);  
   CGImageRelease(imageRef);
   image = nil;
}

助けてくれたみんな、ありがとう!あなたの提案だけで、私は途方もない量を学びました。bt と NSZombie を使用するのはこれが初めてでしたが、今ではそれらを宗教的に使用しています! 再度、感謝します!

于 2012-05-24T12:27:12.300 に答える
0

displayImageイメージを保持したいコンパイラに次のように伝えます__strong

UIImage __strong *outputImage = [UIImage imageWithCGImage:imageRef];

または、必要に応じて:

__strong UIImage *outputImage = [UIImage imageWithCGImage:imageRef];
于 2012-05-20T11:47:47.857 に答える
0

imageRef を解放しているため、UIImage が自動解放されます。

このようなイベントの発生を防ぐために、UIImage を保持していることを確認してください。

- (UIImage *)displayImage
{
    CGContextRef context;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    context = CGBitmapContextCreate(rgbaDataNew, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast ); 

    CGImageRef imageRef = CGBitmapContextCreateImage (context);
    UIImage *outputImage = [[UIImage imageWithCGImage:imageRef] retain]; 

    CGColorSpaceRelease(colorSpace);    
    CGContextRelease(context);  
    CGImageRelease(imageRef); //this line would cause outputImage to be released
    return outputImage;
}
于 2012-05-19T12:21:02.517 に答える