Най-бързото 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, просто използвам необработените данни. Предполагам, че използването на GPU за завъртане на изображението е по-бързо от DSP чрез рамката Accelerate. Не знам дали това е вярно, но това е друга област, в която бих се радвал да имам опит. Истинският въпрос е колко голямо изображение мога да завъртя по време на опресняване на екрана (при всеки кадър в секунда). След като разбера кой е най-бързият начин да го направя, мога да пробвам изображения с различни размери, докато достигна скоростта, от която се нуждая. - person user938797; 19.05.2015
comment
тази библиотека GPUImage също може да помогне, не съм напълно сигурен в нейните възможности, но може би има нещо, което можете да използвате - person Fonix; 19.05.2015
comment
Ще проверя GPUImage Library, вероятно са измислили най-бързия начин да правят нещата, благодаря. - person user938797; 20.05.2015
comment
DisplayLink е инструмент за координация, но не помага за производителността, но добре е да знаете за него. - person user938797; 20.05.2015