2

I'm using the following code to send an image to a web server. It works, the problem is that the images are rotated for some reason when they get uploaded.

here's my upload method:

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

        [self dismissViewControllerAnimated:YES completion:nil];

        NSData *image = UIImageJPEGRepresentation([info objectForKey:UIImagePickerControllerOriginalImage], 0.1);

        // use token with url for json data from contents of url
        NSString *savedValue = [[NSUserDefaults standardUserDefaults]
                                stringForKey:@"token"];

        NSString *urlString = [NSString stringWithFormat:@"%@%@/photos?token=%@", kIDURLPhoto, listingId, savedValue];

        NSLog(@"urlstring for comment is %@",urlString);

        self.flUploadEngine = [[fileUploadEngine alloc] initWithHostName:urlString customHeaderFields:nil];

        NSMutableDictionary *postParams = [NSMutableDictionary dictionaryWithObjectsAndKeys: @"image", @"caption", nil];

        self.flOperation = [self.flUploadEngine postDataToServer:postParams path:nil];
        [self.flOperation addData:image forKey:@"picture" mimeType:@"image/jpeg" fileName:@"upload.jpg"];

        [self.flOperation addCompletionHandler:^(MKNetworkOperation* operation) {
            NSLog(@"%@", [operation responseString]);

    //         handle a successful 200 response

        [self.flUploadEngine enqueueOperation:self.flOperation];

        // for iOS7
        if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {

            [[UIApplication sharedApplication] setStatusBarHidden:YES];
        }

        [self forceReload];

    }
hanumanDev
  • 6,592
  • 11
  • 82
  • 146

2 Answers2

13

Swift 5 Extension:

extension UIImage {
    /// Fix image orientaton to protrait up
    func fixedOrientation() -> UIImage? {
        guard imageOrientation != UIImage.Orientation.up else {
            // This is default orientation, don't need to do anything
            return self.copy() as? UIImage
        }

        guard let cgImage = self.cgImage else {
            // CGImage is not available
            return nil
        }

        guard let colorSpace = cgImage.colorSpace, let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
            return nil // Not able to create CGContext
        }

        var transform: CGAffineTransform = CGAffineTransform.identity

        switch imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x: size.width, y: size.height)
            transform = transform.rotated(by: CGFloat.pi)
        case .left, .leftMirrored:
            transform = transform.translatedBy(x: size.width, y: 0)
            transform = transform.rotated(by: CGFloat.pi / 2.0)
        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: size.height)
            transform = transform.rotated(by: CGFloat.pi / -2.0)
        case .up, .upMirrored:
            break
        @unknown default:
            fatalError("Missing...")
            break
        }

        // Flip image one more time if needed to, this is to prevent flipped image
        switch imageOrientation {
        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x: size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x: size.height, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
        case .up, .down, .left, .right:
            break
        @unknown default:
            fatalError("Missing...")
            break
        }

        ctx.concatenate(transform)

        switch imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
        default:
            ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            break
        }

        guard let newCGImage = ctx.makeImage() else { return nil }
        return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up)
    }
}

Objective C Code :

-(UIImage *)scaleAndRotateImage:(UIImage *)image{
        // No-op if the orientation is already correct
        if (image.imageOrientation == UIImageOrientationUp) return image;

        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        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;
}

Use of code

 UIImage *img=[info objectForKey:UIImagePickerControllerOriginalImage];

 img=[self scaleAndRotateImage:img];
 NSData *image = UIImageJPEGRepresentation(img, 0.1);
Kirit Modi
  • 23,155
  • 15
  • 89
  • 112
kirti Chavda
  • 3,029
  • 2
  • 17
  • 29
  • have you checked my answer ? – kirti Chavda Oct 21 '13 at 12:53
  • This isn't necessary at all. The server should decode the EXIF data and display the image at the correct orientation. – David Snabel-Caunt Oct 21 '13 at 12:54
  • @DavidCaunt i solved this issue using this code so i gives suggestion – kirti Chavda Oct 21 '13 at 12:57
  • thanks @kirtimali. I'm getting the warning "incompatible pointer types assigning to NSData from UIImage with the following line. How did you resolve that?: NSData *image = UIImageJPEGRepresentation([info objectForKey:UIImagePickerControllerOriginalImage], 0.1); image=[self scaleAndRotateImage:image]; – hanumanDev Oct 21 '13 at 13:55
  • The code looks like it is from this [SO answer](http://stackoverflow.com/a/10602363/451475) with minor changes. – zaph Jan 07 '15 at 16:16
2

Most probably you are not taking into account exif data, they give the rotation of the camera and you should add them to the image EXIF dictionary. In this way when you open the image the reading software can rotate the image accordingly. Check this question and relative answers, it would be helpful

Community
  • 1
  • 1
Andrea
  • 26,120
  • 10
  • 85
  • 131