2009-08-11 6 views
33

Sto ricevendo UIimages dalla fotocamera e l'assegnazione a UIImageViews da visualizzare. Quando faccio questo la fotocamera mi dà un'immagine 1200 x 1600 pixel che poi assegno ad un UIImageView nella mia applicazione. L'immagine viene visualizzata come previsto nella vista dell'immagine in questa condizione. Tuttavia, quando provo a ridimensionare la UIImage recuperata prima di assegnarla a UIImageView, l'immagine sta ridimensionando come previsto ma c'è un problema in quel punto (nel codice RESIZING?) Il mio UIImage sta diventando ruotato ... Di conseguenza, quando assegno l'UIImage ridimensionate a un'UIImageView l'immagine viene ruotata di 90 gradi e appare allungata come il rapporto di aspetto (1200 x 1600 pixel) è rimasto invariato ...Il ridimensionamento di UIimages estratto dalla fotocamera comporta anche la rotazione della UIimage?

sto usando questo per ottenere un UIImage dalla fotocamera:

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

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

} 

sto usando questo per ridimensionarla:

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

DOMANDA: Come RIDIMIZZARE un UIImmagine estratto dalla fotocamera SENZA ruotare i pixel?

risposta

60

Il motivo per il codice non funziona è perché l'imageOrientation sul codice che hai non viene preso in considerazione. In particolare, se imageOrientation è destra/sinistra, è necessario ruotare l'immagine e la larghezza/altezza dello swap. Ecco un codice per fare questo:

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

Questo ridimensionerà l'immagine e la ruoterà con l'orientamento corretto. Se avete bisogno della definizione per radianti, che è:

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

La risposta Daniel ha dato è anche corretto, ma soffre il problema che non è thread-safe, dal momento che si sta utilizzando UIGraphicsBeginImageContext(). Dal momento che il codice precedente utilizza solo le funzioni CG, tutto è pronto. Ho anche una funzione simile per ridimensionare e riempire le immagini in modo corretto - fammi sapere se è quello che stai cercando.

Nota: ho ottenuto la funzione originale da this post e ho apportato alcune modifiche per farlo funzionare su JPEG.

+0

Sì. Ottima risposta - Grazie. – RexOnRoids

+0

Proprio quello di cui avevo bisogno (per un progetto diverso). Grazie! –

+0

Grazie, è fantastico! –

11

ho avuto anche questo problema con una parte del codice là fuori, ho trovato questo codice che funziona, il check-out, fatemi sapere cosa si trova

+ (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

questo codice non tiene conto dell'orientamento della telecamera. semplicemente ridimensiona l'immagine alla dimensione specificata. – npellow

+0

no, ma puoi facilmente richiedere l'orientamento e inviare le misure appropriate in là ... – Daniel

+2

questo codice sembrava tener conto dell'orientamento della videocamera nel mio progetto .. – geekinit

1

Se si desidera creare un'immagine quadrata da un'immagine rettangolare (non orizzontale o verticale) ritagliandola per larghezza o altezza su entrambi i lati, utilizzare il mio codice. La differenza è che non mi stiramento, ma ritaglia. Feci dal codice superiore mediante modifica:

//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

aggiungo questo didFinishPickingMediaWithInfo metodo e quindi utilizzare image senza preoccuparsi per la sua rotazione.

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() 
}