UIImagePickerController возвращает неправильную ориентацию изображения - PullRequest
10 голосов
/ 14 февраля 2011

Я использую UIImagePickerController, чтобы захватить изображение, а затем сохранить его. Однако, когда я пытаюсь изменить его масштаб, значение ориентации, которое я получаю из этого изображения, неверно. Когда я делаю снимок, держа телефон Вверх, это дает мне ориентацию влево. Кто-нибудь сталкивался с этой проблемой?

Словарь UIImagePickerController показывает следующую информацию:

{
    UIImagePickerControllerMediaMetadata =     {
        DPIHeight = 72;
        DPIWidth = 72;
        Orientation = 3;
        "{Exif}" =         {
            ApertureValue = "2.970853654340484";
            ColorSpace = 1;
            DateTimeDigitized = "2011:02:14 10:26:17";
            DateTimeOriginal = "2011:02:14 10:26:17";
            ExposureMode = 0;
            ExposureProgram = 2;
            ExposureTime = "0.06666666666666667";
            FNumber = "2.8";
            Flash = 32;
            FocalLength = "3.85";
            ISOSpeedRatings =             (
                125
            );
            MeteringMode = 1;
            PixelXDimension = 2048;
            PixelYDimension = 1536;
            SceneType = 1;
            SensingMethod = 2;
            Sharpness = 1;
            ShutterSpeedValue = "3.910431673351467";
            SubjectArea =             (
                1023,
                767,
                614,
                614
            );
            WhiteBalance = 0;
        };
        "{TIFF}" =         {
            DateTime = "2011:02:14 10:26:17";
            Make = Apple;
            Model = "iPhone 3GS";
            Software = "4.2.1";
            XResolution = 72;
            YResolution = 72;
        };
    };
    UIImagePickerControllerMediaType = "public.image";
    UIImagePickerControllerOriginalImage = "<UIImage: 0x40efb50>";
}

Однако изображение возвращается imageOrientation == 1;

UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage];             

Ответы [ 6 ]

14 голосов
/ 18 февраля 2011

Я только начал работать над этой проблемой в своем собственном приложении.

Я использовал категорию UIImage, созданную Тревором Хармоном для изменения размера изображения и определения его ориентации, UIImage + Resize .

Тогда вы можете сделать что-то подобное в -imagePickerController:didFinishPickingMediaWithInfo:

UIImage *pickedImage = [info objectForKey:UIImagePickerControllerEditedImage];
UIImage *resized = [pickedImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit bounds:pickedImage.size interpolationQuality:kCGInterpolationHigh];

Это исправило проблему для меня. Изображение с измененным размером ориентируется правильно визуально, и свойство imageOrientation сообщает UIImageOrientationUp.

Существует несколько версий этого кода масштабирования / изменения размера / обрезки; Я использовал Trevor, потому что он кажется довольно чистым и включает в себя некоторые другие манипуляторы UIImage, которые я хочу использовать позже.

8 голосов
/ 09 марта 2013

Это то, что я нашел для решения проблемы ориентации;У меня работает

UIImage *initialImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
NSData *data = UIImagePNGRepresentation(self.initialImage);

UIImage *tempImage = [UIImage imageWithData:data];
UIImage *fixedOrientationImage = [UIImage imageWithCGImage:tempImage.CGImage
                                     scale:initialImage.scale
                               orientation:self.initialImage.imageOrientation];
initialImage = fixedOrientationImage;
6 голосов
/ 31 октября 2014

Вот фрагмент кода Swift, который эффективно решает проблему:

let orientedImage = UIImage(CGImage: initialImage.CGImage, scale: 1, orientation: initialImage.imageOrientation)!
0 голосов
/ 10 июля 2018

Единственное, что сработало для меня, - это снова сделать изображение заново, что приводит к правильной ориентации.

if (photo.imageOrientation != .up) {
   UIGraphicsBeginImageContextWithOptions(photo.size, false, 1.0);
   let rect = CGRect(x: 0, y: 0, width: photo.size.width, height: photo.size.height);
   photo.draw(in: rect)
   let newImage = UIGraphicsGetImageFromCurrentImageContext()
   UIGraphicsEndImageContext()
   photo = newImage;
}
0 голосов
/ 03 апреля 2015

В iOS 7 мне требовался код, зависящий от UIImage.imageOrientation, чтобы исправить различные ориентации. Теперь, в iOS 8.2, когда я выбираю свои старые тестовые изображения из альбома через UIImagePickerController, ориентация будет UIImageOrientationUp для ВСЕХ изображений. Когда я делаю фотографию (UIImagePickerControllerSourceTypeCamera), эти изображения также всегда будут направлены вверх, независимо от ориентации устройства. Таким образом, между этими версиями iOS, очевидно, было исправление, при котором UIImagePickerController уже поворачивает изображения, если это необходимо. Вы даже можете заметить, что при отображении изображений альбома: в течение доли секунды они будут отображаться в исходной ориентации, прежде чем появятся в новой восходящей ориентации.

0 голосов
/ 03 мая 2013

Я использую следующий код, который я поместил в отдельный объектный файл утилиты изображений, в котором есть множество других методов редактирования для UIImages:

+ (UIImage*)imageWithImage:(UIImage*)sourceImage scaledToSizeWithSameAspectRatio:(CGSize)targetSize
{
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

    if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;

        if (widthFactor > heightFactor) {
            scaleFactor = widthFactor; // scale to fit height
        }
        else {
            scaleFactor = heightFactor; // scale to fit width
        }

        scaledWidth  = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        // center the image
        if (widthFactor > heightFactor) {
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        }
        else if (widthFactor < heightFactor) {
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
    }

    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);

    }

    // In the right or left cases, we need to switch scaledWidth and scaledHeight,
    // and also the thumbnail point
    if (sourceImage.imageOrientation == UIImageOrientationLeft) {
        thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x);
        CGFloat oldScaledWidth = scaledWidth;
        scaledWidth = scaledHeight;
        scaledHeight = oldScaledWidth;

        CGContextRotateCTM (bitmap, M_PI_2); // + 90 degrees
        CGContextTranslateCTM (bitmap, 0, -targetHeight);

    } else if (sourceImage.imageOrientation == UIImageOrientationRight) {
        thumbnailPoint = CGPointMake(thumbnailPoint.y, thumbnailPoint.x);
        CGFloat oldScaledWidth = scaledWidth;
        scaledWidth = scaledHeight;
        scaledHeight = oldScaledWidth;

        CGContextRotateCTM (bitmap, -M_PI_2); // - 90 degrees
        CGContextTranslateCTM (bitmap, -targetWidth, 0);

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

    CGContextDrawImage(bitmap, CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledWidth, scaledHeight), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage* newImage = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap);
    CGImageRelease(ref);

    return newImage; 
}

А потом я звоню

UIImage *pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
        UIImage *fixedOriginal = [ImageUtil imageWithImage:[mediaInfoDict objectForKey:UIImagePickerControllerOriginalImage] scaledToSizeWithSameAspectRatio:pickedImage.size];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...