iPhone: Cambiar CGImageAlphaInfo de CGImage


Tengo una imagen PNG que tiene un formato de píxel de contexto de gráficos de mapa de bits no compatible. Cada vez que intento cambiar el tamaño de la imagen, CGBitmapContextCreate() se ahoga en el formato no compatible

Recibo el siguiente error (error formateado para facilitar la lectura):

CGBitmapContextCreate: unsupported parameter combination: 
    8 integer bits/component; 
    32 bits/pixel; 
    3-component colorspace; 
    kCGImageAlphaLast; 
    1344 bytes/row.

La lista de formatos de píxeles soportados definitivamente no soporta esta combinación. Parece que necesito volver a dibujar la imagen y mover la información del canal alfa a kCGImageAlphaPremultipliedFirst o kCGImageAlphaPremultipliedLast .

No tengo idea de cómo hacer esto.

No hay nada inusual en el archivo PNG y no está dañado. Funciona en todos los demás contextos muy bien. Encontré este error por casualidad, pero obviamente mis usuarios podrían tener archivos con un formato similar, por lo que tendré que verificar las imágenes importadas de mi aplicación y corregir este problema.

Author: TechZen, 2010-03-16

2 answers

Sí, tuve problemas con 8 bits (indexado) .PNGs. Tuve que convertirlo a una imagen más nativa para realizar operaciones gráficas. Esencialmente hice algo como esto:

- (UIImage *) normalize {

    CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef thumbBitmapCtxt = CGBitmapContextCreate(NULL, 
                                                         self.size.width, 
                                                         self.size.height, 
                                                         8, (4 * self.size.width), 
                                                         genericColorSpace, 
                                                         kCGImageAlphaPremultipliedFirst);
    CGColorSpaceRelease(genericColorSpace);
    CGContextSetInterpolationQuality(thumbBitmapCtxt, kCGInterpolationDefault);
    CGRect destRect = CGRectMake(0, 0, self.size.width, self.size.height);
    CGContextDrawImage(thumbBitmapCtxt, destRect, self.CGImage);
    CGImageRef tmpThumbImage = CGBitmapContextCreateImage(thumbBitmapCtxt);
    CGContextRelease(thumbBitmapCtxt);    
    UIImage *result = [UIImage imageWithCGImage:tmpThumbImage];
    CGImageRelease(tmpThumbImage);

    return result;    
}
 56
Author: Alfons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-20 21:48:06

Aquí hay una versión actualizada del método de Alfons answer para tener en cuenta la escala de pantalla, y también algunos errores tontos con decimales en valores de coma flotante del tamaño de la imagen como se describe en el comentario de unsynchronized de la respuesta original.

SCREEN_SCALE es una macro que devuelve 1.0 si la escala no está definida o cualquiera que sea la escala del dispositivo ([UIScreen MainScreen].escala).

- (UIImage *) normalize {

    CGSize size = CGSizeMake(round(self.size.width*SCREEN_SCALE), round(self.size.height*SCREEN_SCALE));
    CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef thumbBitmapCtxt = CGBitmapContextCreate(NULL, 
                                                         size.width, 
                                                         size.height, 
                                                         8, (4 * size.width), 
                                                         genericColorSpace, 
                                                         kCGImageAlphaPremultipliedFirst);
    CGColorSpaceRelease(genericColorSpace);
    CGContextSetInterpolationQuality(thumbBitmapCtxt, kCGInterpolationDefault);
    CGRect destRect = CGRectMake(0, 0, size.width, size.height);
    CGContextDrawImage(thumbBitmapCtxt, destRect, self.CGImage);
    CGImageRef tmpThumbImage = CGBitmapContextCreateImage(thumbBitmapCtxt);
    CGContextRelease(thumbBitmapCtxt);    
    UIImage *result = [UIImage imageWithCGImage:tmpThumbImage scale:SCREEN_SCALE orientation:UIImageOrientationUp];
    CGImageRelease(tmpThumbImage);

    return result;    
}
 5
Author: psy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-20 22:47:55