2009-04-07 11 views
8

Actualización:edición UIImagePickerController permitidos cerraduras UIImage a tamaño máximo de 320x320

Con el iPhone OS 3.0 o superior, toda la API UIImagePickerController ha cambiado. Esta pregunta y respuesta deben considerarse 2.2. código heredado


Al usar el UIImagePickerController y permite la edición de la imagen. El iPhone permite al usuario cambiar el tamaño y desplazarse por la imagen. Sin embargo, el tamaño máximo de una imagen editada tiene un límite de 320x320.

Como ejemplo, tomé una captura de pantalla de iPhone y la coloqué en la biblioteca de fotos, que es una png de 480x320. Cuando uso un UIImagePickerController para seleccionar esa imagen, incluso si NO escaloo la imagen, se recorta a 320x320 antes de que se devuelva desde el UIImagePickerController. Sin embargo, si desactivo la edición, la imagen se devuelve con el tamaño correcto de 480x320.

Mi teoría: Muy sutilmente, el iPhone muestra 2 barras de herramientas translúcidas no estándar que se superponen sobre la imagen. Estas barras de herramientas dejan una inocuo "ventana" de 320x320 sobre la foto. Me parece que esta ventana efectivamente recorta la foto subyacente.

Nota: La devolución de llamada también devuelve un diccionario de edición con la imagen original y el recorte, pero por supuesto el rect también es máximo de 320x320.

¿Alguna idea sobre cómo permitir escalar y panoramizar imágenes de más de 320x320?

Algunos código:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo { 

     self.myImageView.userInteractionEnabled=YES; 
     CGRect imageFrame = myImageView.frame; 
     CGPoint imageCenter = myImageView.center; 
     imageFrame.size = img.size; 
     myImageView.frame = imageFrame; 
     self.myImageView.image = img; 
     myImageView.center = imageCenter; 

     [self dismissModalViewControllerAnimated:YES]; 
     [self performSelector:@selector(hideToolBars) withObject:nil afterDelay:2.0]; 
    } 
+0

Todavía veo este problema en la versión 3.0.1, ¿está arreglado en 3.1? – Jasarien

Respuesta

7

Como dijo Craig, este es un problema en los foros dev y manzanas de mesa de discusión regular. Lo hice, sin embargo, encontrar una manera de evitarlo. Estoy usando un poco de código a partir de:

Apple Dev Forums

Esto incluye la mayor parte de lo que necesita, y se encarga de todas las cuestiones de orientación de la cámara. He añadido los siguientes elementos que se llevará en la información de edición y utilizarla para conseguir el recorte rect original con esta adición:

- (UIImage*)scaleImage:(UIImage*)anImage withEditingInfo:(NSDictionary*)editInfo{ 

    UIImage *newImage; 

    UIImage *originalImage = [editInfo valueForKey:@"UIImagePickerControllerOriginalImage"]; 
    CGSize originalSize = CGSizeMake(originalImage.size.width, originalImage.size.height); 
    CGRect originalFrame; 
    originalFrame.origin = CGPointMake(0,0); 
    originalFrame.size = originalSize; 

    CGRect croppingRect = [[editInfo valueForKey:@"UIImagePickerControllerCropRect"] CGRectValue]; 
    CGSize croppingRectSize = CGSizeMake(croppingRect.size.width, croppingRect.size.height); 

    CGSize croppedScaledImageSize = anImage.size; 

    float scaledBarClipHeight = 80; 

    CGSize scaledImageSize; 
    float scale; 

    if(!CGSizeEqualToSize(croppedScaledImageSize, originalSize)){ 

     scale = croppedScaledImageSize.width/croppingRectSize.width; 
     float barClipHeight = scaledBarClipHeight/scale; 

     croppingRect.origin.y -= barClipHeight; 
     croppingRect.size.height += (2*barClipHeight); 

     if(croppingRect.origin.y<=0){ 
      croppingRect.size.height += croppingRect.origin.y; 
      croppingRect.origin.y=0; 
     } 

     if(croppingRect.size.height > (originalSize.height - croppingRect.origin.y)){ 
      croppingRect.size.height = (originalSize.height - croppingRect.origin.y); 
     } 


     scaledImageSize = croppingRect.size; 
     scaledImageSize.width *= scale; 
     scaledImageSize.height *= scale; 

     newImage = [self cropImage:originalImage to:croppingRect andScaleTo:scaledImageSize]; 

    }else{ 

     newImage = originalImage; 

    } 

    return newImage; 
} 

He actualizado el método de devolución de llamada de los foros dev correo a la siguiente:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo { 

    [self dismissModalViewControllerAnimated:YES]; 
    self.myImageView.userInteractionEnabled=YES; 
    CGRect imageFrame = myImageView.frame; 
    CGPoint imageCenter = myImageView.center; 
    UIImage *croppedImage; 


    NSMutableDictionary *imageDescriptor = [editInfo mutableCopy]; 

    // CGFloat scaleSize = 400.0f; 
    CGFloat scaleSize = 640.0f; 
    switch ([picker sourceType]) { 
      //done 
     case UIImagePickerControllerSourceTypePhotoLibrary: 
      croppedImage = [self scaleImage:img withEditingInfo:editInfo]; 
      [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
      break; 


     case UIImagePickerControllerSourceTypeCamera: { 
      UIImageOrientation originalOrientation = [[editInfo objectForKey:UIImagePickerControllerOriginalImage] imageOrientation]; 
      if (originalOrientation != UIImageOrientationUp) { 
       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
       CGRect origRect; 
       [[editInfo objectForKey:UIImagePickerControllerCropRect] getValue:&origRect]; 
       UIImage *rotatedImage = straightenAndScaleImage([editInfo objectForKey:UIImagePickerControllerOriginalImage], scaleSize); 
       CGFloat scale = scaleSize/1600.0f; 
       origRect.origin.x *= scale; 
       origRect.origin.y *= scale; 
       origRect.size.width *= scale; 
       origRect.size.height *= scale; 
       croppedImage = [self cropImage:rotatedImage to:origRect andScaleTo:CGSizeMake(320, 480)]; 
       [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
       [pool drain]; 
      } 
      else { 
       croppedImage = [self scaleImage:img withEditingInfo:editInfo]; 
       [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
      } 
     } 
      break; 

     case UIImagePickerControllerSourceTypeSavedPhotosAlbum: { 
      UIImageOrientation originalOrientation = [[editInfo objectForKey:UIImagePickerControllerOriginalImage] imageOrientation]; 
      if (originalOrientation != UIImageOrientationUp) { 
       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
       CGRect origRect; 
       [[editInfo objectForKey:UIImagePickerControllerCropRect] getValue:&origRect]; 
       UIImage *rotatedImage = straightenAndScaleImage([editInfo objectForKey:UIImagePickerControllerOriginalImage], scaleSize); 
       CGFloat scale = scaleSize/640.0f; 
       origRect.origin.x *= scale; 
       origRect.origin.y *= scale; 
       origRect.size.width *= scale; 
       origRect.size.height *= scale; 
       croppedImage = [self cropImage:rotatedImage to:origRect andScaleTo:CGSizeMake(320, 480)]; 
       [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
       [pool drain]; 
      } 
      else { 
       croppedImage = [self scaleImage:img withEditingInfo:editInfo]; 
       [imageDescriptor setObject:croppedImage forKey:@"croppedImage"]; 
      } 
     } 
      break; 
     default: 
      break; 
    } 

    imageFrame.size = croppedImage.size; 
    myImageView.frame = imageFrame; 
    myImageView.image = [imageDescriptor objectForKey:@"croppedImage"]; 
    myImageView.center = imageCenter; 


} 
+0

En lugar de hacer: CGSize originalSize = CGSizeMake (originalImage.size.width, originalImage.size.height); puede hacer CGSize originalSize = originalImage.size.width; –

+0

@Frank - Creo que quieres decir que puedes hacer CGSize originalSize = originalImage.size; – Brian

+0

@Brian - Sí, eso es lo que quise decir. No estoy seguro de cómo el .width llegó allí. ¡Deberías obtener algún tipo de insignia por recoger un error de 3 años! –

1

vale tarde que nunca: aquí está la fuente de la función orientationTransformForImage

 

CGAffineTransform orientationTransformForImage(UIImage *image, CGSize *newSize) { 
    CGImageRef img = [image CGImage]; 
    CGFloat width = CGImageGetWidth(img); 
    CGFloat height = CGImageGetHeight(img); 
    CGSize size = CGSizeMake(width, height); 
    CGAffineTransform transform = CGAffineTransformIdentity; 
    CGFloat origHeight = size.height; 
    UIImageOrientation orient = image.imageOrientation; 
    switch(orient) { /* EXIF 1 to 8 */ 
     case UIImageOrientationUp: 
      break; 
     case UIImageOrientationUpMirrored: 
      transform = CGAffineTransformMakeTranslation(width, 0.0f); 
      transform = CGAffineTransformScale(transform, -1.0f, 1.0f); 
      break; 
     case UIImageOrientationDown: 
      transform = CGAffineTransformMakeTranslation(width, height); 
      transform = CGAffineTransformRotate(transform, M_PI); 
      break; 
     case UIImageOrientationDownMirrored: 
      transform = CGAffineTransformMakeTranslation(0.0f, height); 
      transform = CGAffineTransformScale(transform, 1.0f, -1.0f); 
      break; 
     case UIImageOrientationLeftMirrored: 
      size.height = size.width; 
      size.width = origHeight; 
      transform = CGAffineTransformMakeTranslation(height, width); 
      transform = CGAffineTransformScale(transform, -1.0f, 1.0f); 
      transform = CGAffineTransformRotate(transform, 3.0f * M_PI/2.0f); 
      break; 
     case UIImageOrientationLeft: 
      size.height = size.width; 
      size.width = origHeight; 
      transform = CGAffineTransformMakeTranslation(0.0f, width); 
      transform = CGAffineTransformRotate(transform, 3.0f * M_PI/2.0f); 
      break; 
     case UIImageOrientationRightMirrored: 
      size.height = size.width; 
      size.width = origHeight; 
      transform = CGAffineTransformMakeScale(-1.0f, 1.0f); 
      transform = CGAffineTransformRotate(transform, M_PI/2.0f); 
      break; 
     case UIImageOrientationRight: 
      size.height = size.width; 
      size.width = origHeight; 
      transform = CGAffineTransformMakeTranslation(height, 0.0f); 
      transform = CGAffineTransformRotate(transform, M_PI/2.0f); 
      break; 
     default: 
      ; 
    } 
    *newSize = size; 
    return transform; 
} 
5

debo ser demasiado tarde para responder a esta pregunta, pero tengo una mejor manera t o hacer este trabajo.

static inline double radians (double degrees) {return degrees * M_PI/180;} 

+(UIImage*)editedImageFromMediaWithInfo:(NSDictionary*)info{ 
    if(![info objectForKey:UIImagePickerControllerCropRect])return nil; 
    if(![info objectForKey:UIImagePickerControllerOriginalImage])return nil; 

    UIImage *originalImage=[info objectForKey:UIImagePickerControllerOriginalImage]; 
    CGRect rect=[[info objectForKey:UIImagePickerControllerCropRect] CGRectValue]; 

    CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], rect); 

    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); 
    CGContextRef bitmap = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 

    if (originalImage.imageOrientation == UIImageOrientationLeft) { 
     CGContextRotateCTM (bitmap, radians(90)); 
     CGContextTranslateCTM (bitmap, 0, -rect.size.height); 

    } else if (originalImage.imageOrientation == UIImageOrientationRight) { 
     CGContextRotateCTM (bitmap, radians(-90)); 
     CGContextTranslateCTM (bitmap, -rect.size.width, 0); 

    } else if (originalImage.imageOrientation == UIImageOrientationUp) { 
     // NOTHING 
    } else if (originalImage.imageOrientation == UIImageOrientationDown) { 
     CGContextTranslateCTM (bitmap, rect.size.width, rect.size.height); 
     CGContextRotateCTM (bitmap, radians(-180.)); 
    } 

    CGContextDrawImage(bitmap, CGRectMake(0, 0, rect.size.width, rect.size.height), imageRef); 
    CGImageRef ref = CGBitmapContextCreateImage(bitmap); 

    UIImage *resultImage=[UIImage imageWithCGImage:ref]; 
    CGImageRelease(imageRef); 
    CGContextRelease(bitmap); 
    CGImageRelease(ref); 

    return resultImage; 
} 

Sólo se recorta la imagen original con la relativa CropRect, aunque esta escala método dosen't de la imagen, pero es corto y dulce para mí. Sólo como referencia :)

2

Con el iPhone OS 3.0 o superior, el conjunto UIImagePickerController API ha cambiado . Esta pregunta y respuesta debe considerarse 2.2. código heredado

A pesar de su advertencia, me tomó un dev hora preciosa para darse cuenta de iOS 3.0+ nos dieron UIImagePickerControllerEditedImage lo que hace que se trata de recortar de forma manual para el usuario pizca/zoom y hacer frente a la orientación innecesaria.

Esto es en caso de que alguien siguiera usando UIImagePickerControllerOriginalImage y tratando de encontrar la mejor manera de aplicar el recorte a través de UIImagePickerControllerCropRect, etc. Ya no es necesario.

0

Escribí un category on UIImage que proporciona un recorte de resolución completa. La forma más fácil de instalar es con CocoaPods, agregando UIImage-ImagePickerCrop a su podfile.

#import <UIImage+ImagePickerCrop.h> 

... 

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info { 
    [self dismissViewControllerAnimated:YES completion:nil]; 

    UIImage *croppedImage = [UIImage croppedImageWithImagePickerInfo:info]; 
    ... 
} 
Cuestiones relacionadas