2009-08-11 11 views
33

Obtendré UIimages de la cámara y los asignaré a UIImageViews para que se muestren. Cuando hago esto, la cámara me da una imagen de 1200 x 1600 píxeles que luego asigno a UIImageView en mi aplicación. La imagen se muestra como se espera en la vista de imagen bajo esta condición. Sin embargo, cuando trato de REDIMENSIONAR el UIImage recuperado antes de asignarlo a UIImageView, la imagen cambia de tamaño como se esperaba, pero ¿hay un problema en algún lugar (en el código de RESIZING?) Mi UIImage se está GIRANDO ... Como resultado, cuando se le asigno la UIImage redimensionada a un UIImageView la imagen se gira 90 grados y se ve alargado como la relación de aspecto (1200 x 1600 píxeles) se mantuvo sin cambios ...¿Cambiar el tamaño de UIimages extraído de la cámara también GIRA la UIimage?

estoy usando esto para conseguir un UIImage de la cámara:

- (void) imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info 
{ 

     myImg = [info objectForKey:@"UIImagePickerControllerOriginalImage"]; 
     myResizedImg = [self resizeImage:myImg width:400 height:533]; 
     [myImageView setImage:myResizedImg]; 

} 

estoy usando esta para cambiar su tamaño:

-(UIImage *)resizeImage:(UIImage *)anImage width:(int)width height:(int)height 
{ 

    CGImageRef imageRef = [anImage CGImage]; 

    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef); 

    if (alphaInfo == kCGImageAlphaNone) 
    alphaInfo = kCGImageAlphaNoneSkipLast; 


    CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), 4 * width, CGImageGetColorSpace(imageRef), alphaInfo); 

    CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef); 

    CGImageRef ref = CGBitmapContextCreateImage(bitmap); 
    UIImage *result = [UIImage imageWithCGImage:ref]; 

    CGContextRelease(bitmap); 
    CGImageRelease(ref); 

    return result; 
} 

PREGUNTA: ¿Cómo REDIMO un UIImage extraído de la cámara SIN girar los píxeles?

Respuesta

60

La razón por la que su código no funciona es porque la orientación de la imagen en el código que tienes no se está teniendo en cuenta. Específicamente, si la orientación de la imagen es derecha/izquierda, entonces necesita rotar la imagen y cambiar el ancho/alto. Aquí hay algunos códigos para hacer esto:

-(UIImage*)imageByScalingToSize:(CGSize)targetSize 
{ 
    UIImage* sourceImage = self; 
    CGFloat targetWidth = targetSize.width; 
    CGFloat targetHeight = targetSize.height; 

    CGImageRef imageRef = [sourceImage CGImage]; 
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); 

    if (bitmapInfo == kCGImageAlphaNone) { 
     bitmapInfo = kCGImageAlphaNoneSkipLast; 
    } 

    CGContextRef bitmap; 

    if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) { 
     bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 

    } else { 
     bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 

    } 

    if (sourceImage.imageOrientation == UIImageOrientationLeft) { 
     CGContextRotateCTM (bitmap, radians(90)); 
     CGContextTranslateCTM (bitmap, 0, -targetHeight); 

    } else if (sourceImage.imageOrientation == UIImageOrientationRight) { 
     CGContextRotateCTM (bitmap, radians(-90)); 
     CGContextTranslateCTM (bitmap, -targetWidth, 0); 

    } else if (sourceImage.imageOrientation == UIImageOrientationUp) { 
     // NOTHING 
    } else if (sourceImage.imageOrientation == UIImageOrientationDown) { 
     CGContextTranslateCTM (bitmap, targetWidth, targetHeight); 
     CGContextRotateCTM (bitmap, radians(-180.)); 
    } 

    CGContextDrawImage(bitmap, CGRectMake(0, 0, targetWidth, targetHeight), imageRef); 
    CGImageRef ref = CGBitmapContextCreateImage(bitmap); 
    UIImage* newImage = [UIImage imageWithCGImage:ref]; 

    CGContextRelease(bitmap); 
    CGImageRelease(ref); 

    return newImage; 
} 

Esto cambiará el tamaño de su imagen y la rotará a la orientación correcta. Si necesita la definición de radianes, es:

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

La respuesta de Daniel dio también es correcto, pero adolece del problema de que no es hilo de seguridad, ya que estás usando UIGraphicsBeginImageContext(). Como el código anterior solo usa funciones CG, ya está todo listo. También tengo una función similar para cambiar el tamaño y hacer el relleno de aspecto adecuado en las imágenes. Avíseme si eso es lo que está buscando.

Nota: Obtuve la función original desde this post e hice algunas modificaciones para que funcione en archivos JPEG.

+0

Sí. Gran respuesta - Gracias. – RexOnRoids

+0

Justo lo que necesitaba (para un proyecto diferente). ¡Gracias! –

+0

¡Gracias, esto es fantástico! –

11

tuve este problema también con una parte del código por ahí, me encontré con este código que funciona, mira eso, quiero saber lo que encuentre

+ (UIImage*)imageWithImage:(UIImage*)image 
       scaledToSize:(CGSize)newSize; 
{ 
    UIGraphicsBeginImageContext(newSize); 
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; 
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return newImage; 
} 
+0

Este código no tiene en cuenta la orientación de la cámara. simplemente escala la imagen al tamaño especificado. – npellow

+0

no, pero puede consultar fácilmente la orientación y enviar los tamaños apropiados allí ... – Daniel

+2

este código parece tener en cuenta la orientación de la cámara en mi proyecto ... – geekinit

1

Si desea hacer una imagen cuadrada a partir de una imagen rectangular (no importa horizontal o vertical) recortándola por ancho o alto en ambos lados, use mi código. La diferencia es que no estiro, pero cosecho. Lo hice desde el código de la parte superior mediante la modificación:

//Cropping _image to fit it to the square by height or width 

CGFloat a = _image.size.height; 
CGFloat b = _image.size.width; 
CGRect cropRect; 

if (!(a==b)) { 
    if (a<b) { 
     cropRect = CGRectMake((b-a)/2.0, 0, a, a); 
     b = a; 
    } 
    else if (b<a) { 
     cropRect = CGRectMake(0, (a-b)/2.0, b, b); 
     a = b; 
    } 

    CGImageRef imageRef = CGImageCreateWithImageInRect([_image CGImage], cropRect); 

    UIImage* sourceImage = _image; 
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); 
    CGContextRef bitmap; 
    if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) { 
     bitmap = CGBitmapContextCreate(NULL, a, a, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 

    } else { 
     bitmap = CGBitmapContextCreate(NULL, a, a, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); 
    } 

    if (sourceImage.imageOrientation == UIImageOrientationLeft) { 
     CGContextRotateCTM (bitmap, radians(90)); 
     CGContextTranslateCTM (bitmap, 0, -a); 

    } else if (sourceImage.imageOrientation == UIImageOrientationRight) { 
     CGContextRotateCTM (bitmap, radians(-90)); 
     CGContextTranslateCTM (bitmap, -a, 0); 

    } else if (sourceImage.imageOrientation == UIImageOrientationUp) { 
     // NOTHING 
    } else if (sourceImage.imageOrientation == UIImageOrientationDown) { 
     CGContextTranslateCTM (bitmap, a, a); 
     CGContextRotateCTM (bitmap, radians(-180.)); 
    } 

    CGContextDrawImage(bitmap, CGRectMake(0, 0, a, a), imageRef); 
    CGImageRef ref = CGBitmapContextCreateImage(bitmap); 
    _image = [UIImage imageWithCGImage:ref]; 
    CGImageRelease(imageRef); 
} 
2

Swift 3

agrego esto a didFinishPickingMediaWithInfo método y luego usar image sin tener que preocuparse por su rotación.

var image = info[UIImagePickerControllerOriginalImage] as! UIImage 
if (image.imageOrientation != .up) { 
    UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale) 
    image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)) 
    image = UIGraphicsGetImageFromCurrentImageContext()! 
    UIGraphicsEndImageContext() 
} 
Cuestiones relacionadas