2009-08-11 4 views
33

Я получаю UI изображения из камеры и назначая их UIImageViews для отображения. Когда я делаю это, камера дает мне изображение размером 1200 x 1600 пикселей, которое затем присваиваю UIImageView в моем приложении. Изображение будет отображаться как ожидается в представлении изображения в этом состоянии. Однако, когда я пытаюсь ИЗМЕНИТЬ полученный UIImage, прежде чем назначить его UIImageView, изображение будет изменяться как ожидалось, но проблема в этом где-то (в коде RESIZING?) Мой UIImage получает ROTATED ... В результате, когда я назначаю измененный UIImage в UIImageView, изображение поворачивается на 90 градусов и выглядит растянутым, поскольку соотношение сторон (1200 x 1600 пикселей) не изменилось ...Изменение размера UIimages, снятого с камеры, также ROTATES UIimage?

Я использую это, чтобы получить UIImage от камеры:

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

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

} 

Я использую это, чтобы изменить его размер:

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

ВОПРОС: Как ИЗМЕНИТЬ UIImage, извлеченный из камеры БЕЗ вращений пикселей?

ответ

60

Причина ваш код не работает потому что изображениеОриентирование на код, который у вас есть, не учитывается. В частности, если изображениеОриентация правая/левая, вам необходимо как поворачивать изображение, так и ширину/высоту подкачки. Вот несколько кодов для этого:

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

Это позволит изменить размер изображения и повернуть его в нужной ориентации. Если вам нужно определение для радианов, это:

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

Ответа Даниил дал тоже правильно, но страдает от проблемы, что она не поточно-, так как вы используете UIGraphicsBeginImageContext(). Поскольку приведенный выше код использует только функции CG, вы все настроены. У меня также есть аналогичная функция для изменения размера и выполнения правильного заполнения аспект на изображениях - сообщите мне, если это то, что вы ищете.

Примечание: У меня есть оригинальная функция от this post и внес некоторые изменения, чтобы заставить ее работать с JPEG.

+0

Да. Отличный ответ - Спасибо. – RexOnRoids

+0

Только то, что мне нужно (для другого проекта). Благодаря! –

+0

Спасибо, это фантастика! –

11

У меня была эта проблема тоже с некоторыми из кода там, я нашел этот код, который работает, проверить его, дайте мне знать, что вы нашли

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

Этот код не учитывает ориентацию камеры. он просто масштабирует изображение до указанного размера. – npellow

+0

нет, но вы можете легко запросить ориентацию и отправить соответствующие размеры там ... – Daniel

+2

этот код, по-видимому, учитывал ориентацию камеры в моем проекте. – geekinit

1

Если вы хотите сделать квадратное изображение из изображения прямоугольника (независимо от того, горизонтально или вертикально), обрезая его шириной или высотой с обеих сторон, используйте мой код. Разница в том, что я не растягиваюсь, но урожай. Я сделал это из верхнего кода путем модификации:

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

Свифта 3

добавить это didFinishPickingMediaWithInfo способом, а затем использовать image, не заботясь для его вращения.

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