iPhone 处理图像会停止所有进程
你好,我是 iPhone 开发新手,所以我可能做错了。我想连续转换图像 3 次,但是当我这样做时,它会锁定 iPhone,直到完成所有 3 次转换。我在步骤之间有函数,但在最后一个图像转换触发之前它们不会触发。如果您阅读下面的代码注释,这会更有意义。
我的问题是
是否有更快的方法来转换图像? 2. 如何阻止它锁定,以便它按顺序触发代码,并且图像之间的函数转换为内联触发?
<前><代码>- (IBAction)ColorFun1 { // // 在第三次转换完成之前,此位置中的任何代码都不会触发 // // 要转换的图像 UIImage *originalImage = imageView.image; // 第一次转换 CGColorSpaceRef colorSapce = CGColorSpaceCreateDeviceGray(); CGContextRef context = CGBitmapContextCreate(nil,originalImage.size.width,originalImage.size.height,8,originalImage.size.width,colorSapce,kCGImageAlphaNone); CGContextSetInterpolationQuality(上下文, kCGInterpolationHigh); CGContextSetShouldAntialias(上下文,NO); CGContextDrawImage(上下文, CGRectMake(0, 0, 原始图像.size.宽度, 原始图像.尺寸.高度), [原始图像 CGImage]); CGImageRef bwImage = CGBitmapContextCreateImage(context); // CGContextRelease(上下文); CGColorSpaceRelease(colorSapce); // UIImage *resultImageBW = [UIImage imageWithCGImage:bwImage]; // 这是结果黑白图像。 [fxImage2View setImage:resultImageBW]; // // 在第三次转换完成之前,此位置中的任何代码都不会触发 // // // // 第二次转换 // UIGraphicsBeginImageContext(resultImageBW.size); CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy); [resultImageBW drawInRect:CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height)]; CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeDifference); CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(),[UIColor greyColor].CGColor); CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height)); UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext(); [fxImage1View setImage:returnImage]; UIGraphicsEndImageContext(); // // // // 在第三次转换完成之前,此位置中的任何代码都不会触发 // // // // 第三次转换 // 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 绿色:20 蓝色:0 alpha:1].CGColor); CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, resultImageBW.size.width, resultImageBW.size.height)); returnImage = UIGraphicsGetImageFromCurrentImageContext(); [fxImage3View setImage:returnImage]; UIGraphicsEndImageContext(); CGImageRelease(bwImage); }
Hello I am new to iPhone development so I could be doing this all wrong. I want to convert an image 3 times in a row but when I do it locks up the iphone until it finishes all 3 conversions. I have functions between the steps but they will not fire until the last image convert fires. This make more more sense if you read the code Notes below.
My questions are
Is there a faster way to convert the images? 2. How do I stop it from locking up so that it fires the code in order and the functions between the image converts fire inline?
- (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); }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要像 Sergio 所说的那样将控制权转移回运行循环。我建议研究一下中央调度。来自维基百科
找到有关如何实现它的教程应该不会太难。您甚至可以考虑斯坦福开发讲座。 此讨论了性能和性能线程。我认为与您相关的部分从 33:36 开始。
You need to transfer control back to the run loop like sergio says. I'd suggest looking into grand central dispatch. From wikipedia
It shouldn't be too hard to find a tutorial on how to implement it. You might even consider the Stanford dev lectures. This one talks about performance & threading. I think the part thats relevant to you starts at 33:36.
我认为您的问题取决于这样一个事实:由于您正在执行大量处理而不将控制权返回到主循环,因此您的 UI 在此期间不会更新。
您的一种可能性是定义三种方法,每种方法执行一次图像转换(这也将有助于代码的可读性)。然后,您可以通过在调用之间流程控制返回主循环并更新 UI 的方式来调用它们。
举个例子,如果你的 3 个方法是
convertImage1
、convertImage2
和convertImage3
,你可以这样做:如果您使用 Grand Central Dispatch
dispatch_async
方法来调度您的调用,则可以这样:您可以在此处调整许多设计变量;这只是一个例子,供您参考。
I think that your issue depends on the fact that since you are doing a bunch of processing without returning control back to the main loop, your UI is not updated in between.
One possibility you have is defining three methods, each one doing one image conversion (this will also help readability of your code). Then you can call them in a way that between calls flow control gets back to the main loop and UI is updated.
As an example, if your 3 methods are
convertImage1
,convertImage2
, andconvertImage3
, you can do:The same effect can be obtained in a cleaner way if you use Grand Central Dispatch
dispatch_async
method to dispatch your call:There are many design variables that you can tweak here; this is just an example to give you an idea.