2011-02-16 8 views
5

Tengo una imagen dentro de UIImageView que está dentro de UIScrollView. Lo que quiero hacer es rotar esta imagen 90 grados para que esté en el paisaje por defecto, y establecer el zoom inicial de la imagen para que toda la imagen encaje en la vista de desplazamiento y luego permitir que se amplíe hasta el 100% y volver hasta el zoom mínimo de nuevo.¿Cómo giro UIImageView 90 grados dentro de UIScrollView con el tamaño de imagen correcto y el desplazamiento?

Esto es lo que tengo hasta ahora:

self.imageView.transform = CGAffineTransformMakeRotation(-M_PI/2); 

float minimumScale = scrollView.frame.size.width/self.imageView.frame.size.width; 
scrollView.minimumZoomScale = minimumScale; 
scrollView.zoomScale = minimumScale; 


scrollView.contentSize = CGSizeMake(self.imageView.frame.size.height,self.imageView.frame.size.width); 

El problema es que si fijo la transformación, no aparece nada en el ScrollView. Sin embargo, si comento la transformación, todo funciona, ¡excepto que la imagen no está en la orientación horizontal que quiero que sea!

Si aplico la transformación y elimino el código que establece las propiedades minimumZoomScale y zoomScale, entonces la imagen aparece en la orientación correcta, sin embargo con el zoomScale incorrecto y parece que la propiedad contentSize tampoco está configurada correctamente, ya que el cursor no se desplaza hacia el borde de la imagen en la dirección izquierda/derecha, pero sí arriba y abajo, pero muy por encima del borde.

NB: la imagen se carga desde una URL

+0

¿Hay algún motivo por el que no pueda usar un CGAffineTransformRotate? –

Respuesta

19

Tal vez la rotación de la imagen en sí misma se adapte a sus necesidades:

UIImage* rotateUIImage(const UIImage* src, float angleDegrees) { 
    UIView* rotatedViewBox = [[UIView alloc] initWithFrame: CGRectMake(0, 0, src.size.width, src.size.height)]; 
    float angleRadians = angleDegrees * ((float)M_PI/180.0f); 
    CGAffineTransform t = CGAffineTransformMakeRotation(angleRadians); 
    rotatedViewBox.transform = t; 
    CGSize rotatedSize = rotatedViewBox.frame.size; 
    [rotatedViewBox release]; 

    UIGraphicsBeginImageContext(rotatedSize); 
    CGContextRef bitmap = UIGraphicsGetCurrentContext(); 
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2); 
    CGContextRotateCTM(bitmap, angleRadians); 

    CGContextScaleCTM(bitmap, 1.0, -1.0); 
    CGContextDrawImage(bitmap, CGRectMake(-src.size.width/2, -src.size.height/2, src.size.width, src.size.height), [src CGImage]); 

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return newImage; 
} 
+0

Estoy haciendo una prueba, parece estar dibujando mis imágenes en la orientación correcta, pero está algo aplastado y los bordes superior e inferior están cortados. Entiendo que la primera parte del código tiene el tamaño de la nueva imagen girada en términos de ancho y alto, y la almacena en rotatedSize.El siguiente bit que veo es que define el contexto y lo transforma, he estado jugando con esa parte del código, suponiendo que eso es lo que está causando esta imagen aplastada que se corta en ambos lados. – SMSidat

+0

Gracias, me ayudaste a encontrar errores en mi propio código. He actualizado la respuesta. – Max

+0

Avíseme si corrige el error, Max. He estado jugando con él, sigo aprendiendo, así que probablemente me lleve más tiempo. :) – SMSidat

2

Cualquier cálculo que usted basa en el marco de la imageView probablemente se debe hacer antes de aplicar cualquier transformación a eso. Pero en realidad sugeriría hacer esos cálculos basados ​​en el tamaño del UIImage, no en el UIImageView. A continuación, establezca el marco de UIImageView y el contenido de UIScrollView basado en eso.

La sugerencia de Max es buena, aunque con una imagen más grande podría ser un asesino de rendimiento. ¿Estás mostrando esta imagen desde los recursos de tu aplicación? Si es así, ¿por qué no simplemente rotar las imágenes incluso antes de construir la aplicación?

+0

Gracias, probaré esto también: las imágenes se cargan desde una URL (acaba de editar mi Q) – SMSidat

+0

De la referencia de clase UIView: "si la propiedad transform contiene una transformación no identificada, el valor de la propiedad frame no está definido y no debe ser modificado ". Probablemente se aplica a tu situación. – CharlieMezak

+0

Gracias - Fui por otra solución, que implica dejar la orientación de la imagen tal como está y usar la orientación de la interfaz del iphone para hacerla horizontal (que no es lo que originalmente quería, pero creo que funciona mejor). Creo que con algunos ajustes podría funcionar la sugerencia de Max, y todavía estoy interesado en cómo podría hacerlo funcionar, si tuviera que hacerlo de esta manera particular en el futuro. – SMSidat

3

Creo que la manera más fácil (y seguro para subprocesos también) es hacer:

//assume that the image is loaded in landscape mode from disk 
UIImage * LandscapeImage = [UIImage imageNamed: imgname]; 
UIImage * PortraitImage = [[UIImage alloc] initWithCGImage: LandscapeImage.CGImage 
                scale: 1.0 
               orientation: UIImageOrientationLeft]; 
+0

problema con eso es, que no gira la imagen en sí, solo establece la bandera de Orientación. Esto puede causar problemas si la imagen es procesada por una herramienta que no lee los metadatos de orientación. – Marcin

+0

@Marcin, lo que dices es cierto, pero para aquellos que quieran simplemente rotar la imagen para su visualización sin más procesamiento, esto es suficiente. –

2

Hay una solución mucho más fácil que es también más rápido, acaba de hacer esto:

- (void) imageRotateTapped:(id)sender 
{ 
    [UIView animateWithDuration:0.33f animations:^() 
    { 
     self.imageView.transform = CGAffineTransformMakeRotation(RADIANS(self.rotateDegrees += 90.0f)); 
     self.imageView.frame = self.imageView.superview.bounds; // change this to whatever rect you want 
    }]; 
} 

Cuando el usuario hecho, necesitará crear una nueva imagen girada, pero eso es muy fácil de hacer.

0

Estaba usando la respuesta aceptada por un tiempo hasta que notamos que las rotaciones no cuadradas basadas en imágenes tomadas directamente de la cámara parecían estiradas (se rotaban como se deseaba, solo el ancho/alto del marco no se ajustaba).

gran explicación/post aquí de Trevor: http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

Al final, fue una importación muy simple de código de Trevor categorías que utiliza para agregar un método resizedImage:interpoationQuality a UIImage. Así que sí, cuidado con el usuario, si todavía funciona para ti, genial. Pero si no lo hace, echaré un vistazo a la biblioteca en su lugar.

Cuestiones relacionadas