2011-01-16 19 views
29

Sto usando il seguente codice per eseguire alcune manipolazioni su l'immagine che ho caricato, ma trovo che il display diventa sfocata quando è sul display retinaCoreGraphics per display 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; 
} 

Come posso cambiare questo per renderlo retina compatibile.

Grazie in anticipo per il vostro aiuto

migliore, DV

risposta

47

CGImages non prendere in considerazione il Retina-ness del vostro dispositivo, in modo da avere a farlo da soli.

Per fare questo, è necessario moltiplicare tutte le tue coordinate e dimensioni che utilizzano in CoreGraphics routine dalla proprietà immagine dell'ingresso scale (che sarà 2.0 sui dispositivi retina), per essere sicuri di fare tutte le vostre manipolazioni a doppia risoluzione.

Quindi è necessario modificare l'inizializzazione di resultImage per utilizzare initWithCGImage:scale:orientation: e immettere lo stesso fattore di scala. Questo è ciò che rende i dispositivi Retina il rendering dell'output a risoluzione nativa piuttosto che risoluzione a pixel raddoppiata.

+0

Grazie! Questo metodo ha risolto il mio problema !! – DKV

+1

Se modifichi il CTM (current transform matrix) del tuo contesto chiamando 'CGContextScaleCTM (UIGraphicsGetCurrentContext(), 2, 2)', non è necessario moltiplicare manualmente le coordinate, puoi semplicemente disegnare come faresti con immagini non retinate. – epologee

+14

Siamo spiacenti, è stato troppo veloce con il commento e troppo tardi per la modifica. Se lo fai in questo modo, non devi pensare di ridimensionare tutte le coordinate tu stesso: 'Scala CGFloat = [[Scala schermo UIScreen]]; CGContextScaleCTM (UIGraphicsGetCurrentContext(), scala, scala); ' – epologee

5

Grazie per la risposta, mi ha aiutato! Comunque per essere più chiaro, il codice OP dovrebbe essere cambiato in questo modo:

- (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

versione Swift:

let scale = UIScreen.mainScreen().scale 

    CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale)