2

您好,我是 iPhone 开发的新手,所以我可能做错了。我想连续转换图像 3 次,但是当我这样做时,它会锁定 iphone,直到它完成所有 3 次转换。我在步骤之间有功能,但在最后一个图像转换触发之前它们不会触发。如果您阅读下面的代码注释,这会更有意义。

我的问题是

  1. 有没有更快的方法来转换图像?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);
    
    }
    
4

2 回答 2

2

您需要像 sergio 所说的那样将控制权转移回运行循环。我建议调查大中央调度。来自维基百科

Grand Central Dispatch 仍然在低级别使用线程,但将它们从程序员那里抽象出来,程序员不需要关心那么多细节。GCD 中的任务是轻量级的,易于创建和排队;苹果表示,在 GCD 中排队一个工作单元需要 15 条指令,而创建传统线程可能很容易需要数百条指令

找到有关如何实现它的教程应该不会太难。你甚至可以考虑斯坦福开发讲座。一篇谈论性能和线程。我认为与您相关的部分从 33:36 开始。

于 2011-08-01T15:09:06.627 回答
0

我认为您的问题取决于这样一个事实,即由于您正在进行大量处理而没有将控制权返回到主循环,因此您的 UI 不会在两者之间更新。

您拥有的一种可能性是定义三种方法,每种方法进行一次图像转换(这也将有助于您的代码的可读性)。然后,您可以通过调用之间的流控制返回主循环并更新 UI 的方式调用它们。

例如,如果您的 3 个方法是convertImage1convertImage2convertImage3,您可以执行以下操作:

[self performSelector:@selector(convertImage1) withObject:nil afterDelay:0];
[self performSelector:@selector(convertImage2) withObject:nil afterDelay:0];
[self performSelector:@selector(convertImage3) withObject:nil afterDelay:0];

dispatch_async如果您使用 Grand Central Dispatch方法来调度您的呼叫,则可以以更简洁的方式获得相同的效果:

dispatch_async(dispatch_get_main_queue(), ^{ [self convertImage1]; });
dispatch_async(dispatch_get_main_queue(), ^{ [self convertImage2]; });
dispatch_async(dispatch_get_main_queue(), ^{ [self convertImage3]; });

您可以在此处调整许多设计变量;这只是一个给你一个想法的例子。

于 2011-08-01T14:11:47.987 回答