2015-04-20 6 views
5

Io uso una vista dell'immagine:L'immagine ruotata viene distorta e sfocata?

@IBOutlet weak var imageView: UIImageView! 

a dipingere un'immagine e anche un'altra immagine che è stata ruotata. Si scopre che l'immagine ruotata ha una pessima qualità. Nell'immagine seguente gli occhiali nella scatola gialla non sono ruotati. Gli occhiali nella scatola rossa sono ruotati di 4,39 gradi.

enter image description here

Ecco il codice che uso per disegnare gli occhiali:

UIGraphicsBeginImageContext(imageView.image!.size) 
    imageView.image!.drawInRect(CGRectMake(0, 0, imageView.image!.size.width, imageView.image!.size.height)) 

var drawCtxt = UIGraphicsGetCurrentContext() 

var glassImage = UIImage(named: "glasses.png") 
let yellowRect = CGRect(...) 

CGContextSetStrokeColorWithColor(drawCtxt, UIColor.yellowColor().CGColor) 
CGContextStrokeRect(drawCtxt, yellowRect) 
CGContextDrawImage(drawCtxt, yellowRect, glassImage!.CGImage) 

// paint the rotated glasses in the red square 
CGContextSaveGState(drawCtxt) 
CGContextTranslateCTM(drawCtxt, centerX, centerY) 
CGContextRotateCTM(drawCtxt, 4.398 * CGFloat(M_PI)/180) 
var newRect = yellowRect 
newRect.origin.x = -newRect.size.width/2 
newRect.origin.y = -newRect.size.height/2 
CGContextAddRect(drawCtxt, newRect) 
CGContextSetStrokeColorWithColor(drawCtxt, UIColor.redColor().CGColor) 
CGContextSetLineWidth(drawCtxt, 1) 

// draw the red rect 
CGContextStrokeRect(drawCtxt, newRect) 
// draw the image 
CGContextDrawImage(drawCtxt, newRect, glassImage!.CGImage) 
CGContextRestoreGState(drawCtxt) 

Come posso ruotare e dipingere i vetri senza perdita di qualità o di ottenere un'immagine distorta?

+0

Aiuta a creare il contesto con 'UIGraphicsBeginImageContextWithOptions (..., 0.0)' per ottenere un contesto di disegno che utilizza lo stesso fattore di scala del dispositivo? –

+0

@MartinR quale taglia dovrei usare per generare il contesto? –

risposta

3

È necessario utilizzare UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) per creare il contesto iniziale. Passando allo 0.0 come scale, verrà impostato come valore predefinito la scala della schermata corrente (ad esempio, 2.0 su un iPhone 6 e 3.0 su un iPhone 6 Plus).

Vedi questa nota su UIGraphicsBeginImageContext():

Questa funzione è equivalente a invocare la funzione UIGraphicsBeginImageContextWithOptions con il parametro opaca impostato a NO e un fattore di scala di 1,0.

+0

Cosa fa il parametro '' opaque''? Non ho visto alcuna differenza. –

+1

Documenti: "Se si conosce che la bitmap è completamente opaca, specificare' SÌ' per ignorare il canale alfa e ottimizzare la memoria della bitmap. Specificare 'NO' significa che la bitmap deve includere un canale alfa per gestire i pixel parzialmente trasparenti." – jszumski

1

Come altri hanno sottolineato, è necessario impostare il contesto per consentire la visualizzazione della retina.

Oltre a ciò, è possibile utilizzare un'immagine di origine più grande della dimensione di visualizzazione di destinazione e ridurla. (2X le dimensioni in pixel dell'immagine di destinazione sarebbero un buon punto di partenza.)

La rotazione ad angoli dispari è distruttiva. Il motore grafico deve mappare una griglia di pixel di origine su una griglia diversa in cui non si allineano. Le linee perfettamente dritte nell'immagine sorgente non sono più diritte nell'immagine di destinazione, ecc. Il motore grafico deve fare qualche interpolazione e un pixel sorgente potrebbe essere distribuito su diversi pixel, o meno di un pixel intero, nell'immagine di destinazione.

Fornendo un'immagine di origine più ampia, si fornisce al motore grafico più informazioni con cui lavorare. Può affettare e tagliare meglio quei pixel di origine nella griglia di destinazione dei pixel.