2010-03-16 12 views
25

Tengo una imagen PNG que tiene un formato de píxeles de contexto de gráficos de mapa de bits no admitido. Siempre que intente cambiar el tamaño de la imagen, CGBitmapContextCreate() ahoga en el formato no compatibleiPhone: Cambio de CGImageAlphaInfo de CGImage

recibo el siguiente error (error de formato de fácil lectura):

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

El list of supported pixel formats definitivamente no es compatible con esta combinación. Parece que necesito volver a dibujar la imagen y mover la información del canal alfa al kCGImageAlphaPremultipliedFirst or kCGImageAlphaPremultipliedLast.

No tengo ni idea de cómo hacerlo.

No hay nada de inusual en el archivo PNG y no está dañado. Funciona en cualquier otro contexto sin problemas. Encontré este error por casualidad, pero obviamente mis usuarios pueden tener archivos con el mismo formato, así que tendré que verificar las imágenes importadas de mi aplicación y corregir este problema.

Respuesta

56

Sí, tuve problemas con 8 bits (indexados) .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;  
} 
+0

Se ve bien, lo intentaré. No me gusta hacer mucho procesamiento porque me temo que destruiré sin querer la fidelidad. – TechZen

+0

Finalmente llegué a probar esto y funciona bien sin pérdida perceptible de fidelidad. – TechZen

+0

Tengo un problema con el código anterior cuando la orientación de la imagen del UIImage es cualquier cosa menos OrientationUp: esto hace que la imagen gire. Los límites de la imagen permanecen iguales, pero los píxeles dentro de la imagen se rotan y se estiran para ajustarse a los límites originales. Esto es similar a lo que se describe en: http://stackoverflow.com/questions/5973105/image-clicked-from-iphone-in-portrait-mode-gets-rotated-by-90-degree, pero en este caso es el normalizar la función que parece estar causando el problema. ¿Alguien más ve esto? ¿Alguna solución para esto? – kurtzmarc

5

Aquí es una versión actualizada del método de la respuesta Alfons para dar cuenta de escala de la pantalla, y también algunos errores tontos con decimales en los valores puntuales del tamaño de la imagen flotante tal como se describe en el comentario de no sincronizado de la respuesta original.

SCREEN_SCALE es una macro que devuelve ya sea 1.0 si escala no está definido o lo que sea la escala de 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;  
} 
Cuestiones relacionadas