Pregunta

Estoy tratando de obtener componentes ARGB de CGBitmapContext con los siguientes 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

}

Cuando intento para almacenar rojo / verde / azul, que resultan ser siempre 240. Y alfa es siempre 255.

Así que creo que tal vez algo está mal con el puntero. No podría devolver los datos correctos ARGB que quiero. Alguna idea acerca de lo que está mal con el código?

¿Fue útil?

Solución

En primer lugar, usted está perdiendo memoria, la memoria pixelData nunca se liberó.

Para su uso, es mejor dejar que las llamadas CGContext gestionar la memoria. Basta con pasar i.s.o. NULL pixelData, y siempre y cuando mantenga el recuento de referencia arriba en su contexto, el CGBitmapContextGetData(context) seguirá siendo válida.

Usted está utilizando alfa como si fuera la última entrada (RGBA, no ARGB), usarlo como tal en la creación de su contexto, o adaptar el código alphaAtX. No estoy seguro de si quieres premultiplicado, si es sólo para comprobar valores alfa, no lo hace.

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

con ser contexto una variable miembro, inicializado a NULL, ya habrá un paso en la dirección correcta.

Otros consejos

En primer lugar, me gustaría comprobar para ver si el contexto regresó de su llamada CGBitmapContextCreate es válido (es decir, asegurarse de context != NULL). También me gustaría comprobar para asegurarse de que su imagen cargada originalmente es válido (es así, asegúrese de que img != nil).

Si el contexto es nula, puede ser debido a que su tamaño de la imagen no es razonable, o bien su formato de datos de píxel no está disponible. Trate de usar kCGImageAlphaPremultipliedLast lugar?

En segundo lugar, no es necesario utilizar CGBitmapContextGetData - sólo puede utilizar el puntero pixelData que ha pasado en el primer lugar. También debe CGContextRelease su contexto antes de salir de su función initWithImage: para evitar una fuga.

También observo que está utilizando kCGImageAlphaPremultipliedFirst. Esto significa que el componente alfa es primero , no dura, en su imagen, por lo que desea un desplazamiento de 0 para el componente alfa en su función alphaAtX:y:.

¿Alguno de esa ayuda?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top