2010-04-22 18 views
28

To naprawdę ból, ale zawsze, gdy rysuję UIImage w -drawRect :, jest odwrócony do góry nogami.Jak skompensować odwrócony układ współrzędnych grafiki głównej dla łatwego rysowania?

Po odwróceniu współrzędnych obraz jest rysowany poprawnie, ale kosztem wszystkich innych funkcji CG jest rysowanie "źle" (odwrócone).

Jaka jest Twoja strategia, gdy musisz rysować obrazy i inne rzeczy? Czy jest jakaś reguła, jak nie utknąć w tym problemie w kółko?

Jedną z nieprzyjemnych rzeczy, gdy odwracam oś Y, jest to, że mój CGRect z ramki UIImageView jest nieprawidłowy. Zamiast oczekiwanego pojawienia się 10,10 u góry po lewej stronie pojawia się na dole.

Ale jednocześnie wszystkie normalne funkcje rysowania linii CGContext przyjmują prawidłowe współrzędne. narysowanie linii w -suWybierz ze źródłem 10,10 u góry po lewej, zacznie się naprawdę od górnego lewego rogu. Ale w tym samym czasie jest to dziwne, ponieważ główna grafika ma odwrócony układ współrzędnych z y 0 na dole.

Wygląda więc na to, że coś tam jest naprawdę niekonsekwentne. Rysowanie za pomocą funkcji CGContext przyjmuje współrzędne jako "oczekiwane" (cmon, nikt nie myśli we współrzędnych zaczynając od lewego dolnego, to jest głupie), podczas gdy rysowanie dowolnego obrazu nadal działa "w niewłaściwy" sposób.

Czy używasz metod pomocniczych do rysowania obrazów? A może jest coś użytecznego, co sprawia, że ​​rysowanie obrazów nie jest bolesne w tyłku?

Odpowiedz

27

Problem: Początek znajduje się w lewym dolnym rogu; dodatni y idzie w górę (ujemny y idzie w dół).
Cel: Pochodzenie w lewym górnym rogu; pozytywny y idzie w dół (ujemny y idzie w górę).

Rozwiązanie:

  1. Move pochodzenie przez wysokość widoku za.
  2. Negacja (pomnożenie przez -1) oś Y.

Sposobem na to w kodzie jest translate przez pochylenia widok granic i scale przez (1, -1), w tej kolejności.

Jest kilka części z Quartz 2D Programming Guide, które dotyczą tego tematu, w tym “Drawing to a Graphics Context on iPhone OS” i całego chapter on Transforms. Oczywiście, naprawdę powinieneś przeczytać całość.

+0

Tak, prawda. Ale kiedy przetłumaczyć i odwrócić, wszystkie inne funkcje rysowania CG, takie jak rysowanie linii itp., Wydają się źle rysować. Masz więc wybór: błędne obrazy lub złe ścieżki. Lub cały czas w tę iz powrotem. – dontWatchMyProfile

+0

mystify: Możesz podzielić kod flip-space na metodę i/lub użyć gstate, aby zapisać i przywrócić klapkę, ale zobacz drugą odpowiedź, którą właśnie napisałem. –

2

To naprawdę ból, ale zawsze, gdy rysuję UIImage w-drawRect :, jest odwrócony do góry nogami.

Czy mówisz UIImage, aby narysować, czy uzyskać jego CGImage i rysunek?

Jak wspomniano w “Drawing to a Graphics Context on iPhone OS”, UIImages są świadome różnicy w współrzędnych przestrzeni i powinny narysować się prawidłowo, bez konieczności samodzielnego przerzucania współrzędnych przestrzeni.

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; 
} 

połączeń powyższa metoda za pomocą poniższego kodu: oferty tego kodu z coraz lewą połowę obrazu z istniejącego UIImageView i ustawienie wytworzonego w ten sposób obraz do nowego ImageView - imgViewleft

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

Lepszą odpowiedzią na ten problem jest użycie metody UIImage do narysowania obrazu. Zakładam, że chcesz, aby obraz obejmował całe granice twojego widoku. To właśnie wpisujesz w swojej metodzie drawRect:.

Zamiast:

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

napisać to:

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

proste .. Kocham cię <3333 –

8

można to zrobić przez zastosowanie affinetransform na punkt, który chcesz przekonwertować we współrzędnych UIKit powiązane. Oto przykład.

// 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); 
Powiązane problemy