2010-04-22 1 views
28

Es ist wirklich ein Schmerz, aber immer, wenn ich ein UIImague zeichne ziehen, ist es auf den Kopf gestellt.Wie kompensiert man das gespiegelte Koordinatensystem von Kerngrafiken für einfaches Zeichnen?

Wenn ich die Koordinaten umblättere, wird das Bild korrekt gezeichnet, aber auf Kosten aller anderen CG-Funktionen wird "falsch" gezeichnet (umgedreht).

Was ist Ihre Strategie, wenn Sie Bilder und andere Dinge zeichnen müssen? Gibt es eine Faustregel, wie man nicht immer wieder in diesem Problem stecken bleibt?

Auch eine unangenehme Sache, wenn ich die Y-Achse kippen ist, dass mein CGRect aus dem UIImageView Rahmen falsch ist. Statt wie erwartet bei 10,10 oben links zu erscheinen, erscheint sie unten.

Aber alle diese normalen Linienzeichnung Funktionen von CGContext nehmen die richtigen Koordinaten. Zeichnen einer Linie in-drawRect mit Ursprung 10,10 oben links, wird wirklich oben links beginnen. Aber zur gleichen Zeit ist das seltsam, weil Core-Grafiken tatsächlich ein umgedrehtes Koordinatensystem mit y 0 am unteren Rand haben.

So scheint es, dass dort etwas wirklich inkonsistent ist. Zeichnen mit CGContext-Funktionen nimmt Koordinaten als "erwartet" (cmon, niemand denkt in Koordinaten beginnend von unten links, das ist albern), während Zeichnen jeder Art von Bild immer noch die "falsche" Art und Weise funktioniert.

Verwenden Sie Hilfsmethoden zum Zeichnen von Bildern? Oder gibt es etwas Nützliches, das das Zeichnen von Bildern nicht zu einem Ärgernis macht?

Antwort

27

Problem: Ursprung befindet sich in der unteren linken Ecke; positives y geht nach oben (negatives y geht nach unten).
Ziel: Ursprung in der oberen linken Ecke; positiv y nach unten gehen (negativ y nach oben gehen).

Lösung:

  1. verschieben Ursprung durch die Ansicht der Höhe.
  2. Die y-Achse negieren (mit -1 multiplizieren).

Der Weg, um dies in dem Code zu tun, ist durch die Ansicht Grenzen Höhe und scale durch (1, -1), in dieser Reihenfolge, um translate auf.

Es gibt ein paar Teile der Quartz 2D Programming Guide, die für dieses Thema relevant sind, einschließlich “Drawing to a Graphics Context on iPhone OS” und das ganze chapter on Transforms. Natürlich solltest du das Ganze wirklich lesen.

+0

Ja, richtig. Aber wenn ich es übersetze und umblättere, scheinen alle anderen CG-Zeichenfunktionen wie das Zeichnen von Linien und so weiter falsch zu zeichnen. Sie haben also die Wahl: falsche Bilder oder falsche Wege. Oder die ganze Zeit hin und her blättern. – dontWatchMyProfile

+0

mystify: Sie könnten den Flip-Space-Code in eine Methode aufteilen und/oder den gstate verwenden, um die Umkehrung zu speichern und wiederherzustellen, aber sehen Sie die andere Antwort, die ich gerade gepostet habe. –

2

Es ist wirklich ein Schmerz, aber immer wenn ich ein UIImage in-drawRect zeichne, ist es auf den Kopf gestellt.

Erzählst du dem UIImage zu zeichnen, oder seine CGImage zu bekommen und das zu zeichnen?

Wie in “Drawing to a Graphics Context on iPhone OS” erwähnt, sind UIImagages sich der Unterschiede in den Koordinatenräumen bewusst und sollten sich korrekt zeichnen, ohne dass Sie Ihren Koordinatenraum selbst umdrehen müssen.

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

Rufen Sie das obige Verfahren den folgenden Code ein: Dieser Code geht es immer die linke Hälfte eines Bildes aus einer bestehenden UIImageView und Einstellen der so erzeugte Bild auf einen neuen Imageview - imgViewleft

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

Die bessere Antwort auf dieses Problem ist die UIImage Methode drawInRect:, um Ihr Bild zu zeichnen. Ich nehme an, Sie möchten, dass das Bild die gesamten Grenzen Ihrer Ansicht überspannt. Dies würden Sie in Ihre drawRect: Methode eingeben.

Statt:

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

: Schreibe:

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

einfach..Love you <3333 –

8

Sie können das tun, indem Sie gelten Affine auf dem Punkt, den Sie in UIKit bezogenen Koordinaten umwandeln möchten. Folgendes ist ein Beispiel.

// 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); 
Verwandte Themen