您好我是iPhone开发的新手,所以我可能做错了。我想连续3次转换图像,但是当我这样做时,它会锁定iphone,直到它完成所有3次转换。我在步骤之间有功能,但在最后一个图像转换为fires之前它们不会触发。如果您阅读下面的代码注释,这将更有意义。
我的问题是
是否有更快的方式转换图像? 2.如何阻止它锁定以便按顺序触发代码并且图像之间的功能可以内联转换?
- (IBAction)ColorFun1
{
//
// ANY CODE IN THIS location will not fire until 3rd convert is finished
//
// Image to convert
UIImage *originalImage = imageView.image;
// 1st Convert
CGColorSpaceRef colorSapce = CGColorSpaceCreateDeviceGray();
CGContextRef context = CGBitmapContextCreate(nil, originalImage.size.width, originalImage.size.height, 8, originalImage.size.width, colorSapce, kCGImageAlphaNone);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextSetShouldAntialias(context, NO);
CGContextDrawImage(context, CGRectMake(0, 0, originalImage.size.width, originalImage.size.height), [originalImage CGImage]);
CGImageRef bwImage = CGBitmapContextCreateImage(context);
//
CGContextRelease(context);
CGColorSpaceRelease(colorSapce);
//
UIImage *resultImageBW = [UIImage imageWithCGImage:bwImage]; // This is result B/W image.
[fxImage2View setImage:resultImageBW];
//
// ANY CODE IN THIS location will not fire until 3rd convert is finished
//
//
//
// 2nd Convert
//
UIGraphicsBeginImageContext(resultImageBW.size);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
[resultImageBW drawInRect:CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height)];
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeDifference);
CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(),[UIColor grayColor].CGColor);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height));
UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
[fxImage1View setImage:returnImage];
UIGraphicsEndImageContext();
//
//
//
// ANY CODE IN THIS location will not fire until 3rd convert is finished
//
//
//
// 3rd Convert
//
UIGraphicsBeginImageContext(resultImageBW.size);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
[resultImageBW drawInRect:CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height)];
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeSoftLight);
CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(),[UIColor colorWithRed:40 green:20 blue:0 alpha:1].CGColor);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height));
returnImage = UIGraphicsGetImageFromCurrentImageContext();
[fxImage3View setImage:returnImage];
UIGraphicsEndImageContext();
CGImageRelease(bwImage);
}
答案 0 :(得分:2)
你需要像塞尔吉奥所说的那样将控制权转移回运行循环。我建议调查盛大的中央调度。来自维基百科
Grand Central Dispatch仍然使用较低级别的线程,但将它们从程序员那里抽象出来,程序员不需要关心那么多细节。 GCD中的任务是轻量级的,用于创建和排队; Apple指出,在GCD中排队工作单元需要15条指令,而创建传统线程可能很容易需要数百条指令
找到如何实现它的教程应该不会太难。你甚至可以考虑斯坦福大学的讲座。 This一个人谈论绩效和穿线。我认为与你相关的部分从33:36开始。
答案 1 :(得分:0)
我认为您的问题取决于这样一个事实,即由于您正在进行大量处理而未将控制权返回到主循环,因此您的UI不会在两者之间进行更新。
您有一种可能性是定义三种方法,每种方法都进行一次图像转换(这也有助于您的代码的可读性)。然后,您可以通过调用流控制返回主循环并更新UI之间的方式调用它们。
例如,如果您的3种方法是convertImage1
,convertImage2
和convertImage3
,则可以执行以下操作:
[self performSelector:@selector(convertImage1) withObject:nil afterDelay:0];
[self performSelector:@selector(convertImage2) withObject:nil afterDelay:0];
[self performSelector:@selector(convertImage3) withObject:nil afterDelay:0];
如果您使用Grand Central Dispatch dispatch_async
方法拨打电话,可以更清晰地获得相同的效果:
dispatch_async(dispatch_get_main_queue(), ^{ [self convertImage1]; });
dispatch_async(dispatch_get_main_queue(), ^{ [self convertImage2]; });
dispatch_async(dispatch_get_main_queue(), ^{ [self convertImage3]; });
你可以在这里调整很多设计变量;这只是一个给你一个想法的例子。