2009-08-11 9 views
33

Otrzymuję UIimages z kamery i przypisuję je do wyświetlania UIImageViews. Kiedy to robię, kamera daje mi obraz o rozdzielczości 1200 x 1600 pikseli, który następnie przypisuję do UIImageView w mojej aplikacji. Obraz jest wyświetlany zgodnie z oczekiwaniami w widoku obrazu w tym stanie. Jednak, gdy próbuję ZMIEŃ ROZMIAR pobranego UIImage przed przypisaniem go do UIImageView, obraz zmienia się zgodnie z oczekiwaniami, ale jest tam problem w tym gdzieś (w kodzie RESIZING?) Mój UIImage jest ROTATED ... W rezultacie, Kiedy przypisuję zmieniony obiekt UII do UIImageView, obraz jest obracany o 90 stopni i wydaje się rozciągnięty, gdy proporcje obrazu (1200 x 1600 pikseli) pozostały niezmienione ...Zmiana rozmiaru interfejsów użytkownika wyrysowanych z aparatu powoduje również OBRÓT interfejsu użytkownika?

Używam tego, aby uzyskać UIImage z kamery:

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

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

} 

używam tego, aby go zmienić rozmiar:

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

PYTANIE: W JAKI SPOSÓB ZMIENIĆ UIImage wyciągnięty z kamery BEZ obracania pikseli?

Odpowiedz

60

Powodem Twój kod nie działa jest spowodowane tym, że imageOrientation na kodzie, który masz, nie jest brany pod uwagę. W szczególności, jeśli imageOrientation jest w prawo/lewo, musisz obrócić obraz i zamienić szerokość/wysokość. Oto kod do wykonania:

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

Spowoduje to zmianę rozmiaru obrazu i obrócenie go do właściwej orientacji. Jeśli potrzebujesz definicję radianach, to jest:

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

Odpowiedź Daniel dał również poprawne, ale cierpi na problem, który nie jest bezpieczny wątku, ponieważ używasz UIGraphicsBeginImageContext(). Ponieważ powyższy kod wykorzystuje tylko funkcje CG, wszystko gotowe. Mam też podobną funkcję do zmiany rozmiaru i wypełniania obrazów odpowiednim aspektem - daj mi znać, jeśli tego właśnie szukasz.

Uwaga: Dostałem oryginalną funkcję od this post i wprowadziłem pewne modyfikacje, aby działało na JPEG.

+0

Tak. Świetna odpowiedź - dzięki. – RexOnRoids

+0

Właśnie tego potrzebowałem (dla innego projektu). Dzięki! –

+0

Dzięki, to jest fantastyczne! –

11

miałem ten problem też niektóre kodu tam, Znalazłem ten kod, który działa, sprawdź to, daj mi znać, co można znaleźć

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

ten kod nie uwzględnia orientacji aparatu. po prostu skaluje obraz do określonego rozmiaru. – npellow

+0

nie, ale możesz łatwo zapytać o orientację i wysłać tam odpowiednie rozmiary ... – Daniel

+2

ten kod wydawał się uwzględniać orientację kamery w moim projekcie. – geekinit

1

Jeśli chcesz zrobić kwadratowy obraz z obrazu prostokątnego (bez względu na to, czy jest poziomy czy pionowy), przycinając go przez szerokość lub wysokość z obu stron, użyj mojego kodu. Różnica polega na tym, że nie rozciągam, ale przycinam. Udało mi się z górnej kodu przez modyfikację:

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

dodać to didFinishPickingMediaWithInfo sposób i następnie za pomocą image bez obawy jego obrotu.

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() 
} 
Powiązane problemy