Pergunta

Eu estou tentando obter componentes ARGB de CGBitmapContext com os seguintes códigos:


-(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

}

Quando eu tentar armazenar vermelho / verde / azul, eles acabam por ser sempre 240. E alpha é sempre 255.

Então, eu acho que talvez algo está errado com o ponteiro. Não poderia retornar os dados corretos ARGB que eu quero. Alguma idéia sobre o que está errado com o código?

Foi útil?

Solução

Em primeiro lugar, você está com vazamento de memória, a memória pixelData nunca é liberado.

Para seu uso, é melhor deixar as chamadas CGContext gerenciar a memória. Simplesmente passar NULL I.S.O. pixelData, e contanto que você mantenha a referência contar no seu contexto, o CGBitmapContextGetData(context) permanecerá válido.

Você está usando alfa como se fosse a última entrada (RGBA, não ARGB), usá-lo como tal na criação do seu contexto, ou adaptar o código alphaAtX. Eu não tenho certeza se você quer premultiplied, se é apenas para verificar alfa valores, você não.

Em suma algo como:

[...]
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);
[...]

com o contexto de ser uma variável de membro, inicializado para NULL, já será um passo na direção certa.

Outras dicas

Em primeiro lugar, gostaria de verificar para ver se o contexto retornou de sua chamada CGBitmapContextCreate é válido (isto é, certifique-se context != NULL). Eu também certifique-se de sua imagem originalmente carregada é válido (por isso, certifique-se img != nil).

Se o seu contexto é nula, pode ser porque o tamanho da imagem não é razoável, ou então o seu formato de dados de pixel não está disponível. Tente usar kCGImageAlphaPremultipliedLast vez?

Em segundo lugar, você não precisa usar CGBitmapContextGetData - você pode apenas usar o ponteiro pixelData você passou no em primeiro lugar. Você também deve CGContextRelease seu contexto antes de deixar a sua função initWithImage: para evitar um vazamento.

Eu também notar que você está usando kCGImageAlphaPremultipliedFirst. Isto significa que o componente alfa é início , não última, na sua imagem, assim que você quer um deslocamento de 0 para o componente alfa em sua função alphaAtX:y:.

Será que nada disso ajuda?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top