我有一个使用相机拍摄图像的应用程序。应用程序可以工作,但速度很慢,处理图像需要大约 10 秒。
我的意思是,旋转、创建缩略图并将它们都保存到闪存中。
应用程序基于 Cordova,但我没有参与其中。这是在旧型号 iPhone 3G 上运行的,但在新型号上尝试这个应用程序并没有产生更好的结果。
主要瓶颈是前面提到的 CGContextDrawImage 和 UIImageJPEGRepresentation 函数。
我不能将该代码分离到第二个线程中,因为结果必须尽快可见。
我搜索了两天,没有找到适用的解决方案。
我还发现了苹果的私有 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,因为它似乎是完整的解决方案。如果事实证明它很复杂,因为我是 Objective-c 菜鸟,我会放 UIProgressView 之类的。
无论如何,感谢所有人的帮助。