1

透明な境界線を持つ画像があり、ここにある Apple ガイドに従って、画像ピクセルを直接操作しようとしています。デバイスで実行すると、すべてが完全に機能します。ただし、シミュレーターでコードを実行すると、この関数を呼び出すたびに画像の透明な境界線がゆっくりと黒くなることがわかります。奇妙なことに、画像データを変更しなくても、この関数を呼び出すたびに透明な境界線が黒くなり始めます。たとえば、画像操作コードが呼び出しCGBitmapContextGetDataても、返されたデータ ポインターを使用しない場合でも、同じ問題が発生します。シミュレーターで問題を解決するには、呼び出しをコメントアウトする必要がありますCGBitmapContextGetData(そしてもちろんデータポインタの解放)。シミュレーターで画像を変更するコード例:

+ (UIImage *) updateImage:(UIImage *)inputImage
{
    UIImage *updatedImage;

    /* Update colors in image appropriately */
    CGImageRef image = [inputImage CGImage];

    CGContextRef cgctx = [ColorHandler CreateARGBBitmapContext:image];
    if (cgctx == NULL)
    {
        // error creating context
        NSLog(@"Error creating context.\n");
        return nil;
    }

    size_t w = CGImageGetWidth(image);
    size_t h = CGImageGetHeight(image);
    CGRect rect = {{0,0},{w,h}};

    // Draw the image to the bitmap context. Once we draw, the memory
    // allocated for the context for rendering will then contain the
    // raw image data in the specified color space.
    CGContextDrawImage(cgctx, rect, image);

    // Now we can get a pointer to the image data associated with the bitmap
    // context.
    void *data = CGBitmapContextGetData(cgctx);

    CGImageRef ref = CGBitmapContextCreateImage(cgctx);
    updatedImage = [UIImage imageWithCGImage:ref];
    // When finished, release the context
    CGContextRelease(cgctx);
    CGImageRelease(ref);

    // Free image data memory for the context
    if (data)
    {
        free(data);
    }

    return updatedImage;    
}

デバイスとシミュレーターの間で画像がどのように管理されるかについてのコメントと回答をここで読みましたが、問題を理解するのに役立ちませんでした。

私と例の唯一の違いは、iOS をターゲットにしているためではなく、CreateARGBBitmapContext呼び出していることです。画像は、iOS デバイスで実行すると、設計どおりに正確に編集されます。CGColorSpaceCreateDeviceRGBCGColorSpaceCreateWithName

現在、この問題をデバッグするためにメイン スレッドですべての画像操作を行っています。

仕様: Mountain Lion、XCode 4.5.2、iOS 6 デバイス、iOS 6 シミュレーター

4

1 に答える 1

0

Quartz がビットマップ(Apple doc)のメモリを割り当てて管理できるようにすることで、問題を解決できました。これを行うために、CGBitmapContextCreateinへの呼び出しを更新しCreateARGBBitmapContextて NULL を渡し、へのすべての参照を削除しましたbitmapData

// Create the bitmap context. We want pre-multiplied ARGB, 8-bits 
// per component. Regardless of what the source image format is 
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
context = CGBitmapContextCreate (NULL,
                                pixelsWide,
                                pixelsHigh,
                                8,      // bits per component
                                bitmapBytesPerRow,
                                colorSpace,
                                kCGImageAlphaPremultipliedFirst);

次に、updateImageメソッドで、の解放を削除しましたdata。現在、デバイスとシミュレータの両方で問題なく動作しているようです。

于 2012-11-09T17:11:07.540 に答える