4

I have a problem i got a UIImage from imagePicker (camera not library) but when i write it to file with [UIImageJPEGRepresentation writeToFile: atomically:] i'm loosing orientation data(all images are in landscape), i used some code with image transformation, but it take too long about 1,5 - 2 sec per image, my question is how to not loose orientation ? Maybe i can write it to EXIF data ? Thx for help.

EDIT: Thx to Jonathan Cichon, now i got a image orientation with UIImagePickerControllerMediaMetadata i got (Orientation = 6), but how to store it to jpg file ? (again i saved file with [UIImageJPEGRepresentation writeToFile: atomically:] proc)

itworksinua
  • 127
  • 2
  • 14

2 Answers2

4

Look at this post for information on how to store EXIF data. If i remember correctly you can use the UIImagePickerControllerMediaMetadata as it is. At least you should find all necassary orientation information in this dictionary to create your EXIF data.

Look at the best rated Answer of the linked post and replace the first line with

NSData * jpeg = UIImageJPEGRepresentation(yourImage, 1);
Community
  • 1
  • 1
Jonathan Cichon
  • 4,396
  • 16
  • 19
  • Yes, this is correct i got Orientation = 6, but how to add it to file which i saved with [UIImageJPEGRepresentation writeToFile: atomically:] ? – itworksinua Aug 24 '12 at 13:59
  • the simplest way is add the EFIX container befor saving the file, look at my edit. – Jonathan Cichon Aug 24 '12 at 14:09
  • Ok, now i can write and read exif in both cases i got same value, let's say it's 6, but on my UIImageView it appears in landscape mode instead of portrait. UIImageView read EXIF so maybe i need to store it in other key(now it on "Orientation") ? – itworksinua Aug 24 '12 at 14:52
  • try the `kCGImagePropertyTIFFDictionary` and the `kCGImagePropertyTIFFOrientation` key. – Jonathan Cichon Aug 24 '12 at 15:03
  • Sorry, it was my mistake, all works like a charm Note: kCGImagePropertyTIFFDictionary is a constant of "Orientation" so it's same Note2: UIImageView works correct with orientation, i used MWPhotoBrowser which not works good with orientation. Summary i save image with Orientation key and it appears on UIImageView correct. Thanks to you and your help. – itworksinua Aug 24 '12 at 15:45
  • Thank you! According to your suggestion, I've solved the orientation issue by using UIImageJPEGRepresentation/UIImagePNGRepresentation and also replaced CGImageDestinationAddImage by CGImageDestinationAddImageFromSource. – Nianliang Nov 23 '14 at 03:38
3

Ok What I found in simple google search is as below from this link

UIImage *scaleAndRotateImage(UIImage *image)
{
    int kMaxResolution = 320; // Or whatever

    CGImageRef imgRef = image.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);
    if (width > kMaxResolution || height > kMaxResolution) {
        CGFloat ratio = width/height;
        if (ratio > 1) {
            bounds.size.width = kMaxResolution;
            bounds.size.height = bounds.size.width / ratio;
        }
        else {
            bounds.size.height = kMaxResolution;
            bounds.size.width = bounds.size.height * ratio;
        }
    }

    CGFloat scaleRatio = bounds.size.width / width;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = image.imageOrientation;
    switch(orient) {

        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);
        CGContextTranslateCTM(context, -height, 0);
    }
    else {
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy;
}
The iOSDev
  • 5,237
  • 7
  • 41
  • 78
  • Read carefully i used this method, but it's to slow. – itworksinua Aug 24 '12 at 13:33
  • i think their is a mistake, because EXIF = 8 it's UIImageOrientationLeft not UIImageOrientationRight – zeus Jul 14 '18 at 20:53
  • That needs to be checked as It is very old post may be at the time of the writing the conditions are proper but in current, there may be some change in the conditions. I will check and update the answer if required. – The iOSDev Jul 16 '18 at 06:10