2010-04-22 11 views
28

Realmente es un dolor, pero siempre cuando dibujo un UIImage en -drawRect :, está al revés.¿Cómo se puede compensar el sistema de coordenadas volteado de los gráficos centrales para dibujar fácilmente?

Cuando giro las coordenadas, la imagen se dibuja correctamente, pero a costa de que todas las demás funciones de CG dibujen "mal" (volteado).

¿Cuál es su estrategia cuando tiene que dibujar imágenes y otras cosas? ¿Hay alguna regla práctica de cómo no atascarse en este problema una y otra vez?

Además, una cosa desagradable cuando cambio el eje y es que mi CGRect del marco UIImageView está equivocado. En lugar de que el origen aparezca en 10,10 superior izquierda como se esperaba, aparece en la parte inferior.

Pero al mismo tiempo, todas las funciones normales de dibujo de líneas de CGContext toman las coordenadas correctas. dibujando una línea en -drawRect con origen 10,10 superior izquierda, realmente comenzará en la esquina superior izquierda. Pero al mismo tiempo es extraño, porque los gráficos centrales en realidad tienen un sistema de coordenadas volteado con y 0 en la parte inferior.

Parece que algo es realmente inconsistente allí. Dibujar con las funciones de CGContext toma coordenadas como "esperadas" (cmon, nadie piensa en coordenadas comenzando desde abajo a la izquierda, eso es una tontería), mientras que dibujar cualquier tipo de imagen todavía funciona de manera "incorrecta".

¿Utiliza métodos de ayuda para dibujar imágenes? ¿O hay algo útil que hace que el dibujo de la imagen no sea un problema en el trasero?

Respuesta

27

Problema: el origen está en la esquina inferior izquierda; positivo y va hacia arriba (negativo y va hacia abajo).
Objetivo: Origen en la esquina superior izquierda; positivo yendo hacia abajo (negativo y yendo hacia arriba).

Solución:

  1. origen Mover hacia arriba por la altura de la vista.
  2. Negar (multiplicar por -1) el eje y.

La manera de hacer esto en el código es a translate por altura la vista límites y scale por (1, -1), en ese orden.

Hay un par de porciones de Quartz 2D Programming Guide que son relevantes para este tema, incluyendo “Drawing to a Graphics Context on iPhone OS” y el total chapter on Transforms. Por supuesto, realmente deberías leer todo el asunto.

+0

Sí, claro. Pero cuando lo traduzco y lo volteo, todas las demás funciones de dibujo CG, como dibujar líneas, etc. parecen dibujar mal. Entonces usted tiene la opción: imágenes incorrectas o caminos equivocados. O dando vueltas y vueltas todo el tiempo. – dontWatchMyProfile

+0

mystify: Puede dividir el código de espacio en un método y/o usar el gstate para guardar y restaurar el flip, pero vea la otra respuesta que acabo de publicar. –

2

Realmente es un dolor, pero siempre cuando dibujo un UIImage en -drawRect :, está al revés.

¿Le está diciendo al UIImage que dibuje, o que obtenga su CGImage y dibuje eso?

Como se menciona en “Drawing to a Graphics Context on iPhone OS”, los UIImages son conscientes de la diferencia en los espacios de coordenadas y deben dibujarse correctamente sin tener que voltear el espacio de coordenadas usted mismo.

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

llamada el método anterior con el siguiente código: ofertas de este código con conseguir la mitad izquierda de una imagen de un UIImageView existentes y el establecimiento de la imagen generada de este modo a un nuevo 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 mejor respuesta a este problema es utilizar el método UIImagedrawInRect: para dibujar su imagen. Supongo que quiere que la imagen abarque todos los límites de su vista. Esto es lo que escribirías en tu método drawRect:.

En lugar de:

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

escribir esto:

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

simple..Te encanta <3333 –

8

Usted puede hacer que al aplicar AffineTransform en el punto que desea convertir en coordenadas relacionadas UIKit. Lo siguiente es un ejemplo.

// 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); 
Cuestiones relacionadas