Самое быстрое вращение изображения 2D для iOS

Я хотел бы повернуть 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;
}

Вопросы: Какой самый быстрый механизм 2D-поворота на iPhone 5 и более поздних версиях?

Какова наибольшая область изображения, которую можно вращать со скоростью не менее 10 кадров в секунду?

Мы работаем с 256 изображениями в градациях серого (я думаю, это должно ускорить процесс).

Если ответ OpenGL, я был бы признателен за код или указатель на место для начала.


person user938797    schedule 19.05.2015    source источник
comment
изображение просто нужно повернуть в приложении? или вы сохраняете повернутое изображение?   -  person Fonix    schedule 19.05.2015
comment
просто в приложении, как только оно повернуто, мы запускаем на нем нашу обработку изображения.   -  person user938797    schedule 19.05.2015
comment
Вы говорите о вращении изображения, намного большего, чем экран. В общем, вы можете сделать это более эффективным, либо вращая только ту часть изображения, которая будет на экране, либо уменьшая разрешение изображения до меньшего размера экрана и поворачивая его.   -  person user1118321    schedule 19.05.2015


Ответы (1)


поэтому быстрая часть вращает изображение с использованием преобразования 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, но у меня есть ощущение, что материал UIGraphicsGetCurrentContext(); не очень хорошо работает с потоками

но я думаю, что независимо от того, какой метод вы используете, OpenGL или другой, ваше узкое место - это просто создание нового UIImage, поэтому я бы не стал слишком беспокоиться об ускорении вращения.

не проверял код, но может быть началом в правильном направлении

не полный ответ, но надеюсь, что это немного поможет

person Fonix    schedule 19.05.2015
comment
Спасибо, я уже в теме, мне нужно посмотреть на displayLink, это новое для меня. Мне не нужен новый UIImage, я просто использую необработанные данные. Я предполагаю, что использование графического процессора для поворота изображения быстрее, чем DSP через структуру Accelerate. Я не знаю, правда ли это, однако, это еще одна область, в которой я был бы признателен за некоторый опыт. Реальный вопрос заключается в том, насколько большое изображение я могу повернуть во время обновления экрана (с каждым кадром в секунду). Как только я узнаю самый быстрый способ сделать это, я могу попробовать изображения разных размеров, пока не добьюсь нужной мне скорости. - person user938797; 19.05.2015
comment
эта библиотека GPUImage также может помочь, не совсем уверен в ее возможностях, но, возможно, в ней есть что-то, что вы могли бы использовать - person Fonix; 19.05.2015
comment
Я проверю библиотеку GPUImage, предположительно, они нашли самый быстрый способ сделать что-то, спасибо. - person user938797; 20.05.2015
comment
DisplayLink — это инструмент координации, но он не влияет на производительность, но об этом полезно знать. - person user938797; 20.05.2015