2011-01-16 13 views
29

que estoy usando el siguiente código para realizar algunas manipulaciones de la imagen que he cargado, pero me parece que la pantalla se vuelve borrosa cuando se está en la pantalla de la retinaCoreGraphics de pantalla de la retina

- (UIImage*)createImageSection:(UIImage*)image section:(CGRect)section 

{ 
float originalWidth = image.size.width ; 
float originalHeight = image.size.height ; 
int w = originalWidth * section.size.width; 
int h = originalHeight * section.size.height; 

CGContextRef ctx = CGBitmapContextCreate(nil, w, h, 8, w * 8,CGImageGetColorSpace([image CGImage]), kCGImageAlphaPremultipliedLast); 
CGContextClearRect(ctx, CGRectMake(0, 0, originalWidth * section.size.width, originalHeight * section.size.height)); // w + h before 
CGContextTranslateCTM(ctx, (float)-originalWidth * section.origin.x, (float)-originalHeight * section.origin.y); 
CGContextDrawImage(ctx, CGRectMake(0, 0, originalWidth, originalHeight), [image CGImage]); 
CGImageRef cgImage = CGBitmapContextCreateImage(ctx); 
UIImage* resultImage = [[UIImage alloc] initWithCGImage:cgImage]; 

CGContextRelease(ctx); 
CGImageRelease(cgImage); 

return resultImage; 
} 

¿Cómo cambio esto para que sea retina compatible.

Gracias de antemano por su ayuda

mejor, DV

Respuesta

47

CGImages no tener en cuenta la Retina-dad de su dispositivo, así que hay que hacerlo por sí mismo.

Para hacer eso, necesita multiplicar todas las coordenadas y tamaños que usa en rutinas CoreGraphics por la propiedad scale de la imagen de entrada (que será 2.0 en dispositivos Retina), para asegurarse de que pueda manipular a doble resolución.

Luego debe cambiar la inicialización de resultImage para usar initWithCGImage:scale:orientation: e ingresar el mismo factor de escala. Esto es lo que hace que los dispositivos Retina procesen la salida con una resolución nativa en lugar de la resolución de píxeles duplicados.

+0

Gracias! ¡Este método resolvió mi problema! – DKV

+1

Si cambia la CTM (matriz de transformación actual) de su contexto llamando a 'CGContextScaleCTM (UIGraphicsGetCurrentContext(), 2, 2)', no necesita multiplicar manualmente sus coordenadas, puede dibujar lo mismo que haría con imágenes sin retina. – epologee

+14

Lo sentimos, fue demasiado rápido con el comentario y demasiado tarde para la edición. Si lo hace de esta manera, no necesita pensar en escalar todas las coordenadas usted mismo: 'escala CGFloat = [[UIScreen mainScreen] scale]; CGContextScaleCTM (UIGraphicsGetCurrentContext(), scale, scale); ' – epologee

5

Gracias por la respuesta, me ayudaron! De todas formas para ser más claro, el código de OP debe cambiarse así:

- (UIImage*)createImageSection:(UIImage*)image section:(CGRect)section   
{ 
    CGFloat scale = [[UIScreen mainScreen] scale]; ////// ADD 

    float originalWidth = image.size.width ; 
    float originalHeight = image.size.height ; 
    int w = originalWidth * section.size.width *scale; ////// CHANGE 
    int h = originalHeight * section.size.height *scale; ////// CHANGE 

    CGContextRef ctx = CGBitmapContextCreate(nil, w, h, 8, w * 8,CGImageGetColorSpace([image CGImage]), kCGImageAlphaPremultipliedLast); 
    CGContextClearRect(ctx, CGRectMake(0, 0, originalWidth * section.size.width, originalHeight * section.size.height)); // w + h before 
    CGContextTranslateCTM(ctx, (float)-originalWidth * section.origin.x, (float)-originalHeight * section.origin.y); 

    CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale); ////// ADD 

    CGContextDrawImage(ctx, CGRectMake(0, 0, originalWidth, originalHeight), [image CGImage]); 
    CGImageRef cgImage = CGBitmapContextCreateImage(ctx); 
    UIImage* resultImage = [[UIImage alloc] initWithCGImage:cgImage]; 

    CGContextRelease(ctx); 
    CGImageRelease(cgImage); 

    return resultImage; 
} 
2

versión Swift:

let scale = UIScreen.mainScreen().scale 

    CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale) 
Cuestiones relacionadas