iPhoneカメラで撮影した画像のUIImageからCGImageを取り出すと90度傾く問題の解決法

iPhoneのカメラで撮った写真をトリミングしたい

UIImagePickerControllerを使って、写真を撮影し、その写真から正方形の領域を切り出したいと考えていました。
軽く調べたら以下のようなコードでできそうだということが分かりました。

- (void)imagePickerController:(UIImagePickerController*)picker
        didFinishPickingImage:(UIImage*)image
                  editingInfo:(NSDictionary*)editingInfo
{
    UIImage* imageOriginal = [editingInfo objectForKey:UIImagePickerControllerOriginalImage];
    CGRect cropRect;
    [[editingInfo objectForKey:UIImagePickerControllerCropRect] getValue:&cropRect];
    CGImageRef imageRef = CGImageCreateWithImageInRect(imageOriginal.CGImage, cropRect);
    UIImage *imageCropped =[UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);   
}

簡単に要約します。
UIImagePickerControllerのeditingInfoから、元の写真と切り出す領域の情報を取得します。
写真を一度CGImageRefに変換すると画像の切り出しができます。
切り出した後、再びUIImageに戻せば完了です。

カメラで撮影した写真が90度左に回転する

ところが、カメラで撮影した写真がなぜか90度左に回転してしまいました。
何かがおかしい。

imageOrientationが関係している?

色々考えた結果、どうやら撮影するときのiPhoneの向きが問題になりそうだということが分かりました。
iPhoneは縦に構えたり、横に構えたりできます。
どの向きになっているかは自動で判別されて、imageOriginal.imageOrientationなどに記録されています。

だから、本来であれば、勝手に正しい向きにしてくれます。
むしろ変な方向に回転させたりはしないはずです。

・・・はずなんですが、どうやらUIImageのCGImageプロパティはこれを判別していないように思います。

一方、カメラの向きを正しく判別して処理を行うメソッドもあります。
drawInRectです。

解決策

そこで、解決策。
drawInRectを使って、元画像を一度書きなおしてみよう。

- (void)imagePickerController:(UIImagePickerController*)picker
        didFinishPickingImage:(UIImage*)image
                  editingInfo:(NSDictionary*)editingInfo
{
    UIImage* imageOriginal = [editingInfo objectForKey:UIImagePickerControllerOriginalImage];
 
    // おまじない始まり
    UIGraphicsBeginImageContext(imageOriginal.size); 
    [imageOriginal drawInRect:CGRectMake(0, 0, imageOriginal.size.width, imageOriginal.size.height)]; 
    imageOriginal = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext();
    // おまじない終わり
 
    CGRect cropRect;
    [[editingInfo objectForKey:UIImagePickerControllerCropRect] getValue:&cropRect];
    CGImageRef imageRef = CGImageCreateWithImageInRect(imageOriginal.CGImage, cropRect);
    UIImage *imageCropped =[UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);   
}

正しく動きました。
果たしてこれで良いのかは微妙だけど、とりあえず。

久々にハマりこんだので、記録。

About katty0324

One comment

Leave a Reply

Scroll To Top