2010-04-22 14 views
28

È davvero un dolore, ma sempre quando disegno una UIImage in -drawRect :, è sottosopra.Come compensare il sistema di coordinate capovolte della grafica di base per un disegno facile?

Quando capovolgo le coordinate, l'immagine si disegna correttamente, ma a costo di tutte le altre funzioni CG che disegnano "sbagliato" (capovolto).

Qual è la tua strategia quando devi disegnare immagini e altre cose? C'è qualche regola empirica su come non rimanere bloccati in questo problema più e più volte?

Inoltre, una cosa brutta quando capovolgo l'asse y è che il mio CGRect dal frame UIImageView è sbagliato. Invece dell'origine che appare a 10,10 in alto a sinistra come previsto, appare in basso.

Ma allo stesso tempo, tutte le normali funzioni di disegno di linea di CGContext assumono le coordinate corrette. disegnando una linea in -drawRect con origine 10,10 in alto a sinistra, inizierà veramente in alto a sinistra. Ma allo stesso tempo è strano, perché la core graphics ha in realtà un sistema di coordinate capovolte con y 0 in basso.

Quindi sembra che qualcosa sia davvero incoerente. Disegnare con le funzioni di CGContext prende le coordinate come "attese" (cmon, nessuno pensa in coordinate a partire da in basso a sinistra, è sciocco), mentre disegnare qualsiasi tipo di immagine funziona ancora in modo "sbagliato".

Utilizzi metodi di supporto per disegnare immagini? O c'è qualcosa di utile che rende il disegno dell'immagine non un dolore nel sedere?

risposta

27

Problema: l'origine è nell'angolo in basso a sinistra; il positivo y sale verso l'alto (il negativo y è verso il basso).
Obiettivo: origine nell'angolo in alto a sinistra; positivo y andando verso il basso (negativo y andando verso l'alto).

Soluzione:

  1. Sposta origine dalla altezza della vista.
  2. Negate (moltiplica per -1) l'asse y.

Il modo per fare questo in codice è quello translate dai altezza la vista limiti e scale da (1, -1), in questo ordine.

ci sono un paio di porzioni del Quartz 2D Programming Guide che sono rilevanti per questo tema, tra cui “Drawing to a Graphics Context on iPhone OS” e tutta la chapter on Transforms. Certo, dovresti davvero leggere tutto.

+0

Sì, giusto. Ma quando mi traduco e capovolgerla, tutte le altre funzioni di disegno in CG come disegnare linee e appaiono così via per disegnare sbagliato. Quindi hai la scelta: immagini sbagliate o percorsi sbagliati. O girando avanti e indietro tutto il tempo. – dontWatchMyProfile

+0

Mystify: Si potrebbe dividere il codice di flip-spazio in un metodo e/o utilizzare il gstate per salvare e ripristinare il flip, ma vedere l'altra risposta che ho appena postato. –

2

È davvero un dolore, ma sempre quando disegno una UIImage in -drawRect :, è sottosopra.

Stai dicendo a UIImage di disegnare, o di ottenere il suo CGImage e di disegnare quello?

Come indicato in “Drawing to a Graphics Context on iPhone OS”, UIImages è consapevole della differenza di spazi di coordinate e deve disegnarsi correttamente senza dover capovolgere il proprio spazio di coordinate.

0
CGImageRef flip (CGImageRef im) { 
    CGSize sz = CGSizeMake(CGImageGetWidth(im), CGImageGetHeight(im)); 
    UIGraphicsBeginImageContextWithOptions(sz, NO, 0); 
    CGContextDrawImage(UIGraphicsGetCurrentContext(), 
         CGRectMake(0, 0, sz.width, sz.height), im); 
    CGImageRef result = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; 
    UIGraphicsEndImageContext(); 
    return result; 
} 

Chiamare il metodo di cui sopra usando il codice seguente: offerte di questo codice con ottenere la metà sinistra di un'immagine da un UIImageView esistente e impostare l'immagine così generato un nuovo imageview - imgViewleft

CGContextRef con = UIGraphicsGetCurrentContext(); 
CGContextDrawImage(con, 
        CGRectMake(0,0,sz.width/2.0,sz.height), 
        flip(leftReference)); 
imgViewLeft = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]; 
4

la risposta migliore a questo problema è quello di utilizzare il metodo drawInRect:UIImage attirare la vostra immagine. Suppongo che tu voglia che l'immagine superi l'intero limite della tua vista. Questo è ciò che devi digitare nel metodo drawRect:.

Invece di:

CGContextRef ctx = UIGraphicsGetCurrentContext(); 
UIImage *myImage = [UIImage imageNamed:@"theImage.png"]; 
CGImageRef img = [myImage CGImage]; 
CGRect bounds = [self bounds]; 
CGContextDrawImage(ctx, bounds, img); 

Scrivi:

UIImage *myImage = [UIImage imageNamed:@"theImage.png"]; 
CGRect bounds = [self bounds]; 
[myImage drawInRect:bounds]; 
+0

semplice..Amore <3333 –

8

Potete farlo da applicare affinetransform sul punto che si desidera convertire in coordinate relative UIKit. Di seguito è riportato un esempio.

// Create a affine transform object 
CGAffineTransform transform = CGAffineTransformMakeScale(1, -1); 
// First translate your image View according to transform 
transform = CGAffineTransformTranslate(transform, 0, - imageView.bounds.size.height); 
// Then whenever you want any point according to UIKit related coordinates apply this transformation on the point or rect. 
// To get tranformed point 
CGPoint newPointForUIKit = CGPointApplyAffineTransform(oldPointInCGKit, transform); 
// To get transformed rect 
CGRect newRectForUIKit = CGRectApplyAffineTransform(oldPointInCGKit, transform); 
Problemi correlati