简体   繁体   English

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

[英]Fastest Image 2D Rotation for iOS

I would like to rotate a 2D image (in the x/y plane) in realtime or near realtime (10 frames per second would be adequate). 我想实时或接近实时旋转2D图像(在x / y平面上)(每秒10帧就足够了)。 The question at hand is how large an image I can rotate at such speeds. 当前的问题是,以这种速度旋转的图像可以放大多少。 The reason that I can't just run the experiment myself is that I can't be sure I'm doing it right. 我不能自己进行实验的原因是我不确定自己做对了。 I am not sure if I get full speed by using CATransform3DRotate, CGAffineTransformMakeRotation or if I have to go to OpenGL. 我不确定是否通过使用CATransform3DRotate,CGAffineTransformMakeRotation来获得全速运行,还是不确定是否必须使用OpenGL。
I am betting that the hardware is intended to rotate screen size images (or smaller) and not full resolution (3226 by 2448) images. 我敢打赌,硬件旨在旋转屏幕尺寸的图像(或更小尺寸),而不是全分辨率(3226 x 2448)图像。 Unfortunately we have to work with images larger than the screen and sometimes as large as the whole sensor. 不幸的是,我们必须处理比屏幕大,有时甚至与整个传感器一样大的图像。 I have implemented rotation with CGAffineTransformMakeRotation and if this is all there is to it then I can start small and build up – is it? 我已经使用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;
}

Questions: What is the fastest 2D rotation mechanism on iPhones 5 and later? 问题:iPhone 5及更高版本上最快的2D旋转机制是什么?

What is the largest image area that can be rotated at at least 10 frames per second? 每秒至少可旋转10帧的最大图像区域是多少?

We are working with 256 grayscale images (which should speed things up, I would think). 我们正在处理256个灰度图像(我认为应该可以加快速度)。

If the answer is OpenGL I would appreciate either code or a pointer to a place to start. 如果答案是OpenGL,我将不胜感激代码或指向起点的指针。

so the fast part is rotating the image using the UIViews transformation, but the slow part is when you are actually writing the rotated pixel data out to another UIImage 所以最快速的部分是使用UIViews转换旋转图像,而最慢的部分是当您实际上将旋转的像素数据写到另一个UIImage时

to run a method continuously linked to the refresh of the screen you can use the CADisplayLink like so 要运行连续链接到屏幕刷新的方法,可以像这样使用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];

inside the render: function you could do something like render:函数中,您可以执行以下操作

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

if you want to speed up the UIImage creation i think you will need to find out how to do it on another thread, could be as easy as putting it inside a dispatch_async block but i have a feeling that UIGraphicsGetCurrentContext(); 如果您想加快UIImage的创建速度,我想您需要找出如何在另一个线程上执行此操作的方法,就像将它放在dispatch_async块中一样容易,但是我感到UIGraphicsGetCurrentContext(); stuff doesnt play nicely with threads 东西与线程的配合不好

but i think no matter what method you use, OpenGL or otherwise, your bottle neck is just the creating the new UIImage so i wouldnt fuss too much about speeding up the rotation 但是我认为无论您使用哪种方法(OpenGL或其他方法),瓶颈都只是创建新的UIImage,所以我不会为加快旋转而大惊小怪

havent tested any of the code but could be a start in the right direction 尚未测试任何代码,但可能是朝着正确方向迈出的第一步

not a complete answer but hope it helps a bit 不是一个完整的答案,但希望能有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM