Как вытащить компонент ARGB из BitmapContext на iPhone? - PullRequest
3 голосов
/ 18 февраля 2009

Я пытаюсь получить компоненты ARGB из CGBitmapContext со следующими кодами:


-(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
}</p>

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

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

}

Когда я пытаюсь сохранить красный / зеленый / синий, они всегда равны 240. А альфа всегда 255.

Так что я думаю, что-то не так с указателем. Не удалось вернуть правильные данные ARGB, которые я хочу. Есть идеи о том, что не так с кодом?

Ответы [ 2 ]

2 голосов
/ 26 марта 2009

Прежде всего, вы теряете память, память pixelData никогда не освобождается.

Для вашего использования лучше позволить вызовам CGContext управлять памятью. Просто передайте NULL i.s.o. pixelData, и пока вы продолжаете подсчет ссылок в вашем контексте, CGBitmapContextGetData(context) останется действительным.

Вы используете альфа, как если бы это была последняя запись (RGBA, а не ARGB), используете ее как таковую при создании контекста или адаптируете код 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);
[...]

с контекстом, являющимся переменной-членом, инициализированной в NULL, уже будет шагом в правильном направлении.

0 голосов
/ 21 марта 2009

Во-первых, я бы проверил, верен ли контекст, возвращаемый из вашего CGBitmapContextCreate вызова (то есть убедитесь, что context != NULL). Я также проверил, чтобы убедиться, что ваше изначально загруженное изображение является действительным (поэтому убедитесь, что img != nil).

Если ваш контекст равен нулю, это может быть связано с тем, что размер вашего изображения неоправдан или ваш формат данных пикселей недоступен. Попробуйте использовать kCGImageAlphaPremultipliedLast вместо?

Во-вторых, вам не нужно использовать CGBitmapContextGetData - вы можете просто использовать указатель pixelData, который вы передали в первую очередь. Вы также должны CGContextRelease свой контекст, прежде чем выходить из функции initWithImage:, чтобы избежать утечки.

Я также отмечаю, что вы используете kCGImageAlphaPremultipliedFirst. Это означает, что альфа-компонент в вашем изображении первый , а не последний, поэтому вы хотите смещение 0 для альфа-компонента в вашей функции alphaAtX:y:.

Помогает ли что-нибудь из этого?

...