Iphone работает с изображениями останавливает все процессы - PullRequest
2 голосов
/ 01 августа 2011

Здравствуйте, я новичок в разработке для 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);
    
    }
    

Ответы [ 2 ]

2 голосов
/ 01 августа 2011

Вам нужно перенести управление обратно в цикл выполнения, как говорит Серхио. Я бы посоветовал заглянуть в центральную диспетчерскую Из википедии

Grand Central Dispatch по-прежнему использует потоки на низком уровне, но абстрагирует их от программиста, которому не нужно беспокоиться о стольких деталях. Задачи в GCD легки для создания и очереди; Apple заявляет, что для постановки в очередь рабочего модуля в GCD требуется 15 инструкций, в то время как для создания традиционного потока может потребоваться несколько сотен инструкций

Не должно быть слишком сложно найти учебник о том, как его реализовать. Вы могли бы даже рассмотреть лекции Стэнфордского разработчика. Этот говорит о производительности и многопоточности. Я думаю, что часть, которая имеет отношение к вам, начинается в 33: 36.

0 голосов
/ 01 августа 2011

Я думаю, что ваша проблема зависит от того факта, что, поскольку вы выполняете кучу обработки, не возвращая управление обратно в основной цикл, ваш пользовательский интерфейс не обновляется между ними.

Одна из ваших возможностей - определить три метода, каждый из которых выполняет одно преобразование изображения (это также поможет удобочитаемости вашего кода). Затем вы можете вызывать их так, чтобы между вызовами управление потоком возвращалось в основной цикл и обновлялся пользовательский интерфейс.

Например, если вы используете 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]; });

Есть много переменных дизайна, которые вы можете настроить здесь; это просто пример, чтобы дать вам представление.

...