0

I am getting a UIImage with UIImagePickerController. After getting the image, I set it as the background of a UITableView. The image looks exactly as I took it. But then if I save the image to my server and then load the image back. Whether I save using UIImagePNGRepresentation or UIImageJPEGRepresentation, the image rotates upon saving (rotation happens before server call). I have read here that the png would rotate but that the jpeg would not. But for me both rotate 90 degrees. Any thoughts why jpeg is bad in my case?

MORE

I get the raw image from image picker as UIImage. Then I keep a pointer to the UIImage. Some time later, I want to save the UIImage. So normally I do UIImagePNGRepresentation(myUIImage). I am using AFNetworking as

if ([self.imageDictionaries count]>0)
  for (NSDictionary *imgDic in self.imageDictionaries) {
    [formData appendPartWithFileData:UIImagePNGRepresentation([imgDic objectForKey:@"image"])
    name:[imgDic objectForKey:@"name"]//@"image"
    fileName:[imgDic objectForKey:@"fileName"]//@"image.png"
    mimeType:[imgDic objectForKey:@"mimeType"]//@"image/png"
    ];
  }
}
//[imgDic objectForKey:@"name"] is just a UIImage

One of the items of imageDictionaries look like this

NSDictionary *background =@{
                                @"image":self.backgroundImage,
                                @"name":@"bkgimg",
                                @"fileName":@"bkgimg.png",
                                @"mimeType":@"image/png"
                                };

Also note that my code works fine. The one and only problem is that the image is rotating. self.backgroundImage is a pointer to the UIImage that I obtained from UIImagePickerController as

UIImage *background = info[UIImagePickerControllerOriginalImage];

The image does not rotate if I were to use UIImagePickerControllerEditedImage. But that's a whole other story for another time.

Katedral Pillon
  • 14,534
  • 25
  • 99
  • 199
  • You're still not giving me enough to go on. What is `self.imageDictionaries`? – matt Sep 26 '14 at 22:52
  • It's a dictionary where each item is a dictionary containing: UIImage, NSString of imageName, NSString of fileName, NSString of mimeType. The comments near each line shows as well. I will include an example item in the code. So again imageDictionaries is a dictionary of dictionaries. – Katedral Pillon Sep 26 '14 at 22:58

2 Answers2

0

Don't save it with UIImagePNGRepresentation or with UIImageJPEGRepresentation. Use the ImageIO framework. This allows you to save with the correct rotation information.

Alternatively, depending on what you're doing (you didn't explain exactly how you're getting these images), it might suffice to pass through CGImage. You can attach rotation information to that as you wrap that up as a UIImage.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Thanks. I have never heard of the ImageIO framework. I will make a search for it. – Katedral Pillon Sep 26 '14 at 21:50
  • Here's my (brief) intro to it: http://www.apeth.com/iOSBook/ch36.html#_image_file_formats – matt Sep 26 '14 at 21:55
  • I have updated to show that I am a UIImage as given. Do you mind showing how I would pass that UIImage to afnetworking without the png/jpeg representation call? I have added some code – Katedral Pillon Sep 26 '14 at 22:03
  • So you're getting these images from the Internet somehow? Do they contain orientation information? This could be the problem. Check their `imageOrientation` property. – matt Sep 26 '14 at 22:55
0

The image is rotating because you are saving the image in JPEG, if you save your image in PNG then the orientation will not change. here is the code to fix orientation issue.

- (UIImage *)fixrotation:(UIImage *)image{


if (image.imageOrientation == UIImageOrientationUp) return image;
CGAffineTransform transform = CGAffineTransformIdentity;

switch (image.imageOrientation) {
    case UIImageOrientationDown:
    case UIImageOrientationDownMirrored:
        transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
        transform = CGAffineTransformRotate(transform, M_PI);
        break;

    case UIImageOrientationLeft:
    case UIImageOrientationLeftMirrored:
        transform = CGAffineTransformTranslate(transform, image.size.width, 0);
        transform = CGAffineTransformRotate(transform, M_PI_2);
        break;

    case UIImageOrientationRight:
    case UIImageOrientationRightMirrored:
        transform = CGAffineTransformTranslate(transform, 0, image.size.height);
        transform = CGAffineTransformRotate(transform, -M_PI_2);
        break;
    case UIImageOrientationUp:
    case UIImageOrientationUpMirrored:
        break;
}

switch (image.imageOrientation) {
    case UIImageOrientationUpMirrored:
    case UIImageOrientationDownMirrored:
        transform = CGAffineTransformTranslate(transform, image.size.width, 0);
        transform = CGAffineTransformScale(transform, -1, 1);
        break;

    case UIImageOrientationLeftMirrored:
    case UIImageOrientationRightMirrored:
        transform = CGAffineTransformTranslate(transform, image.size.height, 0);
        transform = CGAffineTransformScale(transform, -1, 1);
        break;
    case UIImageOrientationUp:
    case UIImageOrientationDown:
    case UIImageOrientationLeft:
    case UIImageOrientationRight:
        break;
}

// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height,
                                         CGImageGetBitsPerComponent(image.CGImage), 0,
                                         CGImageGetColorSpace(image.CGImage),
                                         CGImageGetBitmapInfo(image.CGImage));
CGContextConcatCTM(ctx, transform);
switch (image.imageOrientation) {
    case UIImageOrientationLeft:
    case UIImageOrientationLeftMirrored:
    case UIImageOrientationRight:
    case UIImageOrientationRightMirrored:
        // Grr...
        CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
        break;

    default:
        CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.CGImage);
        break;
}

// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img; 
}
Jaydeep Patel
  • 1,699
  • 17
  • 30