2009-08-11 9 views
33

Ich erhalte UI-Bilder von der Kamera und ordne sie UIImageViews zur Anzeige zu. Wenn ich das mache, gibt mir die Kamera ein 1200 x 1600 Pixel großes Bild, das ich dann in meiner Anwendung einem UIImageView zuweise. Das Bild wird unter dieser Bedingung wie erwartet in der Bildansicht angezeigt. Wenn ich jedoch versuche, das abgerufene UIImage zu RESIZE, bevor Sie es der UIImageView zuweisen, ändert das Bild wie erwartet, aber es gibt ein Problem, dass irgendwo (im RESIZING-Code?) Meine UIImage rotiert wird ... Als Ergebnis Wenn ich die Größe UIImage einer UIImageView zuweisen, wird das Bild um 90 Grad gedreht und gestreckt angezeigt, da das Seitenverhältnis (1200 x 1600 Pixel) unverändert ist ...Ändern der Größe von UI-Bildern, die von der Kamera gezogen wurden, ROTIERT auch das UI-Bild?

Ich benutze dies, um eine UIImage von der Kamera zu bekommen:

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

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

} 

ich dies benutze es, um die Größe:

FRAGE: Wie grabe ich ein UIImagie aus der Kamera gezogen OHNE die Pixel zu drehen?

Antwort

60

Der Grund Code funktioniert nicht finden, was Sie arbeitet ist, weil die imageOrientation auf den Code, den Sie haben, nicht berücksichtigt wird. Genauer gesagt, wenn die imageOrientation rechts/links ist, müssen Sie sowohl das Bild drehen als auch die Breite/Höhe tauschen. Hier ist ein Code, um dies zu tun:

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

Dies wird die Größe Ihres Bildes und drehen Sie es in die richtige Ausrichtung. Wenn Sie die Definition für Radiant benötigen, ist es:

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

Die Antwort Daniel gab auch richtig, aber es leidet unter dem Problem, dass es ist nicht Thread-sicher-, da Sie UIGraphicsBeginImageContext verwenden(). Da der obige Code nur CG-Funktionen verwendet, sind Sie fertig. Ich habe auch eine ähnliche Funktion zur Größenanpassung und zum Ausfüllen von Bildern mit dem richtigen Aspekt - lassen Sie es mich wissen, wenn Sie danach suchen.

Hinweis: Ich habe die ursprüngliche Funktion von this post, und hat einige Änderungen vorgenommen, damit es mit JPEGs funktioniert.

+0

Ja. Große Antwort - Danke. – RexOnRoids

+0

Genau was ich brauchte (für ein anderes Projekt). Vielen Dank! –

+0

Danke, das ist fantastisch! –

11

ich mit einigen der Code, um dieses Problem zu hatte da draußen, fand ich diesen Code, der, check it out, lassen Sie mich

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

Dieser Code berücksichtigt nicht die Kameraausrichtung. Es skaliert das Bild einfach auf die angegebene Größe. – npellow

+0

nein, aber Sie können leicht zur Orientierung abfragen und die entsprechenden Größen dort hinschicken ... – Daniel

+2

Dieser Code schien die Kameraausrichtung in meinem Projekt zu berücksichtigen. – geekinit

1

Wenn Sie ein quadratisches Bild aus einem Rechteckbild (egal horizontal oder vertikal) erstellen möchten, indem Sie es auf beiden Seiten nach Breite oder Höhe zuschneiden, verwenden Sie meinen Code. Der Unterschied ist, dass ich mich nicht dehne, aber ich schneide. Ich habe es von oben Code durch Änderung:

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

I dies didFinishPickingMediaWithInfo Verfahren hinzufügen und dann image verwenden, ohne für seine Drehung besorgniserregend.

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