iPhone: Cambiando CGImageAlphaInfo de CGImage
png cgbitmapcontextcreate (2)
Tengo una imagen PNG que tiene un formato de píxeles de contexto de gráficos de mapa de bits no compatible. Cuando intento cambiar el tamaño de la imagen, CGBitmapContextCreate()
atraganta con el formato no compatible
Recibo el siguiente error (error formateado para una fácil 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 admitidos definitivamente no admite 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 bien en todos los demás contextos. Encontré este error por casualidad, pero obviamente mis usuarios pueden tener archivos con formato similar, así que tendré que revisar las imágenes importadas de mi aplicación y corregir este problema.
Aquí hay una versión actualizada del método de respuesta de Alfons para dar cuenta de la escala de la pantalla, y también algunos errores tontos con decimales en valores de punto flotante del tamaño de la imagen como se describe en el comentario no sincronizado 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 en realidad es ([UIScreen mainScreen] .scale).
- (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;
}
Sí, tuve problemas con 8 bits (indexados) .PNGs. Tuve que convertirlo en una imagen más nativa para realizar operaciones gráficas. Básicamente 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;
}