3

次のコードを使用して、CGBitmapContext から ARGB コンポーネントを取得しようとしています。


-(id) initWithImage: (UIImage*) image   //create BitmapContext with UIImage and use 'pixelData' as the pointer
{

        CGContextRef    context = NULL;
        CGColorSpaceRef colorSpace;
        int             bitmapByteCount;
        int             bitmapBytesPerRow;

        bitmapBytesPerRow   = (image.size.width * 4);                       
        bitmapByteCount     = (bitmapBytesPerRow * image.size.height);

        colorSpace = CGColorSpaceCreateDeviceRGB();                         
        pixelData = malloc( bitmapByteCount );      //unsigned char* pixelData is defined in head file
        context = CGBitmapContextCreate (pixelData,                         
                        image.size.width,
                        image.size.height,
                        8,    // bits per component
                        bitmapBytesPerRow,
                        colorSpace,
                        kCGImageAlphaPremultipliedFirst
                        );
        CGColorSpaceRelease( colorSpace );                                  

        CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
        pixelData = CGBitmapContextGetData(context);
        return self;
}


-(float) alphaAtX:(int)x y:(int)y   //get alpha component using the pointer 'pixelData' 
{
    return pixelData[(y *width + x) *4 + 3];    //+0 for red, +1 for green, +2 for blue, +3 for alpha
}

-(void)viewDidLoad { [super viewDidLoad]; UIImage *img = [UIImage imageNamed:@"MacDrive.png"]; //load image

[self initWithImage:img];   //create BitmapContext with UIImage
float alpha = [self alphaAtX:20 y:20];  //store alpha component

}

赤/緑/青を保存しようとすると、常に 240 であることがわかります。また、アルファは常に 255 です。

したがって、ポインターに問題がある可能性があると思います。必要な正しい ARGB データを返すことができませんでした。コードの何が問題なのかについてのアイデアはありますか?

4

2 に答える 2

2

まず第一に、あなたはメモリをリークしています.pixelDataメモリは決して解放されません.

使用方法としては、CGContext 呼び出しでメモリを管理できるようにすることをお勧めします。NULL iso pixelData を渡すだけで、コンテキストで参照カウントを維持している限り、CGBitmapContextGetData(context)有効なままになります。

アルファを最後のエントリ (ARGB ではなく RGBA) であるかのように使用するか、コンテキストの作成でアルファをそのまま使用するか、alphaAtXコードを適合させます。事前乗算が必要かどうかはわかりませんが、アルファ値を確認するだけの場合は必要ありません。

全体として、次のようなものです。

[...]
CGContextRelease(context);
context = CGBitmapContextCreate (NULL,                                                     
                                    image.size.width,
                                    image.size.height,
                                    8,    // bits per component
                                    bitmapBytesPerRow,
                                    colorSpace,
                                    kCGImageAlphaLast
                                    );
CGColorSpaceRelease( colorSpace );                                                                      

CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
pixelData = CGBitmapContextGetData(context);
[...]

context がメンバー変数であり、NULL に初期化されている場合、すでに正しい方向への一歩になります。

于 2009-03-26T12:26:15.890 に答える
0

まず、CGBitmapContextCreate呼び出しから返されたコンテキストが有効かどうかを確認します (つまり、確認しcontext != NULLます)。また、最初に読み込まれた画像が有効であることを確認します (したがって、確認してくださいimg != nil)。

コンテキストが nil の場合、画像サイズが不適切であるか、ピクセル データ形式が利用できないことが原因である可能性があります。kCGImageAlphaPremultipliedLast代わりに使ってみませんか?

第 2 に、使用する必要はありません。最初に渡したポインターをそのままCGBitmapContextGetData使用できます。リークを避けるために、関数を終了する前にコンテキストpixelDataも必要です。CGContextReleaseinitWithImage:

を使用していることにも注意してくださいkCGImageAlphaPremultipliedFirst。これは、アルファ コンポーネントがイメージの最後ではなく最初にあることを意味するため、関数内のアルファ コンポーネントのオフセットを 0 にする必要がありますalphaAtX:y:

それは役に立ちますか?

于 2009-03-21T00:34:10.090 に答える