58

When obtaining a UIImage of a video via AVAssetImageGenerator, I'm getting back images rotated (well, technically they're not) when the video is shot in portrait orientation. How can I tell what orientation the video was shot and then rotate the image properly?

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset];
NSError *err = NULL;
CMTime time = CMTimeMake(0, 60);
CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:NULL error:&err];
[generate release];
UIImage *currentImg = [[UIImage alloc] initWithCGImage:imgRef];
E-Madd
  • 4,414
  • 5
  • 45
  • 77

4 Answers4

239

The easiest way is to just set the appliesPreferredTrackTransform property on the image generator to YES, then it should automatically do the transformation for you.

Anomie
  • 92,546
  • 13
  • 126
  • 145
  • 1
    Many thanks! I skimmed the docs but the name of this property just didn't suggest to me it had anything to do with the problem. – E-Madd Mar 18 '11 at 04:02
  • For some reason, setting it to `YES` (also tried `NO` too, no difference) didn't do anything and it's still rotated. (the asset is encapsulated by a `GPUImageMovie`, if that helps). – Can Poyrazoğlu Apr 17 '17 at 07:03
25

The copy and paste solution to create image with the recording orientation using the previous answer.

AVURLAsset* asset = [AVURLAsset URLAssetWithURL:url options:nil];
AVAssetImageGenerator* imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
imageGenerator.appliesPreferredTrackTransform = YES;
CGImageRef cgImage = [imageGenerator copyCGImageAtTime:CMTimeMake(0, 1) actualTime:nil error:nil];
UIImage* image = [UIImage imageWithCGImage:cgImage];

CGImageRelease(cgImage);
ant_one
  • 845
  • 11
  • 11
8

Here is the solution in swift version 4:

func thumbnailImageForFileUrl(_ fileUrl: URL) -> UIImage? {
    let asset = AVAsset(url: fileUrl)
    let imageGenerator = AVAssetImageGenerator(asset: asset)
    imageGenerator.appliesPreferredTrackTransform = true

    do {

        let thumbnailCGImage = try imageGenerator.copyCGImage(at: CMTimeMake(1, 60), actualTime: nil)
        return UIImage(cgImage: thumbnailCGImage)

    } catch let err {
        print(err)
    }

    return nil
}
Amrit Sidhu
  • 1,870
  • 1
  • 18
  • 32
1

the easiest way is

imageGenerator.appliesPreferredTrackTransform = true

the hardest way is to change image orientation by this code:

let orient: UIImage.Orientation = isVertical ? .left: .up
imageView.image = UIImage(cgImage: image.cgImage!, scale: image.scale, orientation: orient)
jamal zare
  • 1,037
  • 12
  • 13