适用于iOS的最快图像2D旋转

时间:2015-05-19 00:48:24

标签: ios objective-c opengl-es rotation cgaffinetransform

我想实时或接近实时地旋转2D图像(在x / y平面中)(每秒10帧就足够了)。手头的问题是我能以这样的速度旋转多大的图像。我不能自己进行实验的原因是我不能确定我做得对。我不确定我是否通过使用CATransform3DRotate,CGAffineTransformMakeRotation或者我必须转到OpenGL来获得全速。 我打赌硬件的目的是旋转屏幕尺寸图像(或更小)而不是全分辨率(3226×2448)图像。不幸的是,我们必须处理大于屏幕的图像,有时甚至与整个传感器一样大。 我已经使用CGAffineTransformMakeRotation实现了旋转,如果这就是全部,那么我可以从小开始构建 - 是吗?

UIImage * ImageRotatedByRadians(UIImage *oldImage, CGFloat radians)
{
NSLog( @"\n\nRotateImage->imageRotatedByRadians: (%f)\n\n", radians );

// Calculate the size of the rotated view's containing box for our drawing space.
UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake( 0, 0, oldImage.size.width, oldImage.size.height )];
CGAffineTransform t = CGAffineTransformMakeRotation( radians );
rotatedViewBox.transform = t;
CGSize rotatedSize = rotatedViewBox.frame.size;

// Create the bitmap context.
UIGraphicsBeginImageContext( rotatedSize );
CGContextRef bitmap = UIGraphicsGetCurrentContext();

// Move the origin to the middle of the image so we will rotate and scale around the center.
CGContextTranslateCTM( bitmap, rotatedSize.width / 2, rotatedSize.height / 2 );

// Rotate the image context.
CGContextRotateCTM( bitmap, radians );

// Now, draw the rotated/scaled image into the context.
CGContextScaleCTM( bitmap, 1.0, -1.0 );
CGContextDrawImage( bitmap, CGRectMake( -oldImage.size.width / 2, -oldImage.size.height / 2, oldImage.size.width, oldImage.size.height), [oldImage CGImage] );

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil);

UIGraphicsEndImageContext();

return newImage;
}

问题: 什么是iPhone 5及更高版本上最快的2D旋转机制?

可以以每秒至少10帧的速度旋转的最大图像区域是什么?

我们正在使用256张灰度图像(我认为这应该可以加快速度)。

如果答案是OpenGL,我会很感激代码或指向要开始的地方的指针。

1 个答案:

答案 0 :(得分:0)

因此快速部分使用UIViews变换旋转图像,但慢速部分是当您实际将旋转像素数据写入另一个UIImage时

运行一个连续刷新屏幕的方法,你可以使用CADisplayLink这样的

//inside viewDidLoad or something
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)]; //implement a method called render or some other name
displayLink.frameInterval = 2; // 2 = 30fps, 1 = 60fps 3 = 20fps etc basically the frameInterval = 60/frameInterval
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

render:函数中,您可以执行类似

的操作
- (void)render:(CADisplayLink*)displayLink {
    rotatedBoxView.transform = CGAffineTransformMakeRotation( radians );
    //do other image stuff
}

如果你想加快UIImage的创建,我认为你需要找到如何在另一个线程上做到这一点,就像把它放在dispatch_async块里一样简单,但我有一种感觉{ {1}}东西不能很好地与线程一起使用

但我认为无论你使用什么方法,OpenGL或其他方式,你的瓶颈只是创造新的UIImage,所以我不会为加快轮换而烦恼太多

没有测试任何代码,但可能是正确方向的开始

不是一个完整的答案,但希望它有所帮助