2010-05-18

iPhoneアプリ開発: CGImageRefを回転する

CGImageRefをアフィン変換で回転させる方法。
ググったらいい感じのコードが見つかったのですが、今作成に関わっているアプリのソースコード(たぶん座標系が普通と違います。90度回転してそう)に単純にコピペしてみたら微妙に上手くいきませんでした。

コピー元:How can I modify this code, which rotates a CGImage, not to crop the image on rotate? - Stack Overflow

とりあえず次のように修正したら、思い通りに動いたのでメモ。

- (CGImageRef)CGImageRotatedByAngle:(CGImageRef)imgRef angle:(CGFloat)angle
{
 CGFloat angleInRadians = angle * (M_PI / 180);
 CGFloat width = CGImageGetWidth(imgRef);
 CGFloat height = CGImageGetHeight(imgRef);
 
 CGRect imgRect = CGRectMake(0, 0, width, height);
 CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
 CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
 CGContextRef bmContext = CGBitmapContextCreate(NULL,
               rotatedRect.size.width,
               rotatedRect.size.height,
               8,
               0,
               colorSpace,
               kCGImageAlphaPremultipliedFirst);
 CGContextSetInterpolationQuality(bmContext, kCGInterpolationNone);
 CGColorSpaceRelease(colorSpace);
 CGContextTranslateCTM(bmContext,
        +(rotatedRect.size.width/2),
        +(rotatedRect.size.height/2));
 CGContextRotateCTM(bmContext, angleInRadians);
 CGContextTranslateCTM(bmContext,
        -(rotatedRect.size.height/2),
        -(rotatedRect.size.width/2));
 CGContextDrawImage(bmContext, CGRectMake(0, 0,
            rotatedRect.size.height,
            rotatedRect.size.width),
        imgRef);
 
 CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
 CFRelease(bmContext);
 [(id)rotatedImage autorelease];
 
 return rotatedImage;
}

このメソッドの使用例は次の通りです。この例ではsrcImageが反時計回りに90度回転します。

CGImageRef dstImage = [self CGImageRotatedByAngle:srcImage angle:90.0];

0 件のコメント: