カメラを使用して画像を撮影するアプリケーションがあります。アプリケーションは動作しますが、非常に遅く、画像の処理に約 10 秒かかります。
プロセスとは、つまり、回転、サムネイルの作成、およびそれらの両方のフラッシュメモリへの保存です。
アプリケーションはCordovaに基づいていますが、私はその一部を持っていません. また、これは古いモデルの iPhone 3G で実行されていますが、このアプリを新しいモデルで試しても、それほど良い結果は得られません。
主なボトルネックは、前述の CGContextDrawImage および UIImageJPEGRepresentation 関数です。
結果をできるだけ早く表示する必要があるため、そのコードを 2 番目のスレッドに分割することはできません。
2 日間検索しましたが、該当する解決策が見つかりませんでした。
また、AppleのプライベートAPIについて知りましたが、使用できません。
タイム クリティカルなコードのコード サンプルを次に示します。これを高速化する方法についてアドバイスがあれば、ぜひお寄せください。
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
NSLog(@"TEST imagePickerController");
NSDate* dateFunctionStart = [NSDate date];
NSLog(@"respond...");
if ([picker respondsToSelector:@selector(presentingViewController)]) {
[[picker presentingViewController] dismissModalViewControllerAnimated:YES];
} else {
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
}
NSLog(@"done");
// get the image
NSLog(@"get the image...");
UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSLog(@"done");
NSLog(@"correct image for orientation...");
image = [self imageCorrectedForCaptureOrientation:image]; // 3 sec
//image = [image rotate:[image imageOrientation]]; // 1 - 6 sec
NSLog(@"done");
NSLog(@"make thumbnail...");
CGSize thumbnailSize = CGSizeMake(200, 200);
UIImage *thumbnailImage = [self imageByScalingNotCroppingForSize:image toSize:thumbnailSize];
NSLog(@"done");
NSLog(@"jpeg representation 1...");
NSData* imageData = UIImageJPEGRepresentation(image, 1.0); // 4 sec
NSLog(@"done");
NSLog(@"jpeg representation 2...");
NSData* thumbnailData = UIImageJPEGRepresentation(thumbnailImage, 1.0);
NSLog(@"done");
NSLog(@"save image and thumbnail...");
NSString* imageRet = [self saveData:imageData toFile:self.imageName];
NSString* thumbRet = [self saveData:thumbnailData toFile:self.thumbnailName];
NSLog(@"done");
NSLog(@"array two images...");
//NSString *jsResult = [NSString stringWithFormat:@"{%@, %@}", imageRet, thumbRet];
NSArray *jsResultA = [NSArray arrayWithObjects:imageRet, thumbRet, nil];
NSLog(@"done");
NSLog(@"plugin stuff...");
CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsArray:jsResultA];
NSString* jsString = [result toSuccessCallbackString:self.callBackID];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
NSLog(@"done");
timeFunc(dateFunctionStart, @"total time");
NSLog(@"TEST END imagePickerController");
}
imageCorrectedForCaptureOrientation
メソッドは次のとおりです。
- (UIImage*) imageCorrectedForCaptureOrientation:(UIImage*)anImage
{
NSLog(@"IMAGE CORRECTION IN");
NSDate* start = nil;
float rotation_radians = 0;
bool perpendicular = false;
switch ([anImage imageOrientation]) {
case UIImageOrientationUp:
rotation_radians = 0.0;
break;
case UIImageOrientationDown:
rotation_radians = M_PI;
break;
case UIImageOrientationRight:
rotation_radians = M_PI_2;
perpendicular = true;
break;
case UIImageOrientationLeft:
rotation_radians = -M_PI_2;
perpendicular = true;
break;
default:
break;
}
UIGraphicsBeginImageContext(CGSizeMake(anImage.size.width, anImage.size.height));
CGContextRef context = UIGraphicsGetCurrentContext();
// Rotate around the center point
CGContextTranslateCTM(context, anImage.size.width/2, anImage.size.height/2);
CGContextRotateCTM(context, rotation_radians);
CGContextScaleCTM(context, 1.0, -1.0);
float width = perpendicular ? anImage.size.height : anImage.size.width;
float height = perpendicular ? anImage.size.width : anImage.size.height;
CGContextDrawImage(context, CGRectMake(-width / 2, -height / 2, width, height), [anImage CGImage]);
// Move the origin back since the rotation might've change it (if its 90 degrees)
if (perpendicular) {
CGContextTranslateCTM(context, -anImage.size.height/2, -anImage.size.width/2);
}
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSLog(@"IMAGE CORRECTION OUT");
return newImage;
}
それ以外に画像を保存するより良い方法が見つかりませんでした
NSData* imageData = UIImageJPEGRepresentation(image, 1.0); // 4 sec
通常のカメラ アプリケーションはどのように高速に動作しますか? 画像を取得し、回転させ、画像をフラッシュに保存します。その効果を生み出す方法は?
どんな助けでも大歓迎です。
編集:解決策はありません。何かが起こっていることをユーザーに通知するために、いくつかのアニメーションを再生するカスタム UIView を配置します。イメージは 1.5 MB と大きいため、これらの操作にはしばらく時間がかかります。画像を取得して処理し、ディスクに保存するこのプロセス全体を高速化する解決策があるかもしれませんが、私はそれを知りません。
完全なソリューションのように見えるので、 https://github.com/matej/MBProgressHUDを決定しました。私が客観的な初心者であるため、複雑であることが判明した場合は、UIProgressView などを配置します。
とにかく、助けてくれてありがとう。