2014년 10월 29일 수요일

iOS에서 카메라로 찍은 사진 정방향으로 돌리기(rotate UIImage)

카메라로 찍은 사진을 파일로 떨궈보니(PNG, JPG) 이상하게 방향이 회전되서 나온다.

갤러리로 보면 정상적으로 나오는데....

예를 들어, 아이폰에서 정방향이라 함은 홈버튼이 아래에 있을 때 정방향이다. 이 상태에서 사진을 찍어 파일로 떨궈보면, 사진이 왼쪽으로 회전되어 있는 것을 알 수 있다. 왜 이렇게 되어 있는지 이해가 안된다;;;

아무튼 카메라나 갤러리에서 사진을 찍거나 가져올 때, UIImagePickerController를 사용하는데 UIImage를 보면 방향정보가 있다.

UIImageOrientation이라는 구조체가 있는데, 이 값을 보고 다시 회전을 시킨 후 저장해야, 갤러리에서 보이는 것처럼 볼 수 있다.

 그래서 구글에서 코드를 좀 찾고 수정을 해봤는데, 내가 주석으로 달아놓은 것이 맞는지 잘 모르겠다. 회사 과장님은 이렇게 이해하는게 맞다고 하는데....뭐가 맞는지;

암턴 누가 이 코드를 쓰신다면 주석이 맞게 달려있는지....제가 이해를 제대로 하고 있는건지 댓글로 의견 좀 달아주시면 감사하겠습니다.


- (UIImage*) rotateUIImage:(UIImage*) src orientation:(UIImageOrientation)ori
{  
if( ori == UIImageOrientationUp )
return src;

int nDegree = 0;
CGFloat width, height;

width = src.size.width;
height = src.size.height;

//90도로 회전할 경우, 높이와 넓이를 바꿔준다. 필요없는 경우에는 생략해도 된다.(카메라로 찍은 이미지를 화면에 보이는 것 처럼 저장하려면, 회전이 필요하다.)
//UIImage의 UIImageOrientation은 현재 이미지의 방향을 나타낸다.
switch( ori )
{
case UIImageOrientationDown : //케이블 꽂는 곳이 왼쪽. 뒤집힘.(레티나의 경우 960 x 720)
nDegree = 180;
break;
case UIImageOrientationLeft : //케이블 꽂는 곳이 위쪽. 왼쪽으로 회전됨.(레티나의 경우 720 x 960)
width = src.size.height;
height = src.size.width;
nDegree = -90;
break;
case UIImageOrientationRight : //케이블 꽂는 곳이 아래쪽. 오른쪽으로 회전됨.(레티나의 경우 720 x 960)
width = src.size.height;
height = src.size.width;
nDegree = 90;
break;
case UIImageOrientationUp: //케이블 꽂는 곳이 오른쪽. 정방향(레티나의 경우 960 x 720)
default :
nDegree = 0;
break;
}

//UIView를 통해서 이미지를 회전했을 때의 크기를 구함.
//90도와 -90도의 경우, 960 x 720으로 들어온다. 위에서 값을 변경했으므로.
    UIView* rotatedViewBox = [[UIView alloc] initWithFrame: CGRectMake(0, 0, width, height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(nDegree));
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;
    [rotatedViewBox release];
//90도와 -90도의 경우 위 코드를 지나면, 결국 다시 720 x 960이 된다.

//위에서 변경한 크기로 컨텍스트 이미지를 만든다.
    UIGraphicsBeginImageContext(rotatedSize);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

//기준점을 이미지의 중간으로 변경한다. 센터 기준 회전을 하기 위해서.
//CTM은 Current Translate Matrix의 약자같음.
//원래 이미지는 720 x 960이 되고, 가져온 컨텍스를 이리저리 회전시켜, 원래의 720 x 960이미지를 만드는 것 같다.
//즉, UIGraphicsBeginImageContext로 만든 이미지가 회전되는 것이 아닌 것 같다. 원본 이미지에 그리는데, 회전을 시켜서 원본에 그려라~이 의미 인듯.
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

//기준점을 기준으로 각도만큼 회전한다.
    CGContextRotateCTM(bitmap, DEGREES_TO_RADIANS(nDegree));

    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-width / 2, -height / 2, width, height), [src CGImage]);

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

댓글 없음: