Как обрабатывать CIFilter, используя CPU вместо GPU?

Кто-нибудь знает, как указать основному образу обрабатывать CIImage через CIFilter с использованием ЦП вместо графического процессора? Мне нужно обработать несколько очень больших изображений, и я получаю странные результаты при использовании графического процессора. Меня не волнует, сколько времени потребуется, чтобы процессор был в порядке.


person Kevin Gross    schedule 09.10.2010    source источник


Ответы (3)


Ключевым здесь является kCIContextUseSoftwareRenderer:

+ (CIContext*)coreContextFor:(NSGraphicsContext *)context forceSoftware:(BOOL)forceSoftware
{
    //CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    NSDictionary *contextOptions = [NSDictionary dictionaryWithObjectsAndKeys:
                                    (id)colorSpace, kCIContextWorkingColorSpace,
                                    (id)colorSpace, kCIContextOutputColorSpace,
                                    [NSNumber numberWithBool:forceSoftware], kCIContextUseSoftwareRenderer,
                                    nil];
    CIContext* result = [CIContext contextWithCGContext:(CGContext *)[context graphicsPort] options:contextOptions];
    CGColorSpaceRelease(colorSpace);
    return result;
}

Рендеринг в программном обеспечении (CPU) решает некоторые проблемы, но... Снижение производительности на современных машинах настолько велико, что я не могу сказать, что это решение. Я использую CoreImage в своих приложениях и всегда делаю рендеринг с помощью графического процессора на экране, в то время как принудительный процессор используется только для сохранения. Я заметил, что рендеринг процессора на моем тестовом оборудовании немного точнее, а сохранение отфильтрованного изображения — долгий процесс, здесь я могу пожертвовать скоростью.

person Gobra    schedule 01.11.2010
comment
Спасибо. Я попробую. То, что я пробовал, было очень похоже, но оно никогда не работало правильно (вместо этого оно всегда работало на графическом процессоре). - person Kevin Gross; 02.11.2010
comment
// создать CIContext, который позволяет пользователю указать, что изображение визуализируется с использованием ЦП - (CIContext *)CPUonlyCIContextFromCGContext:(CGContextRef)cgContext withFlag:(BOOL)flag { NSDictionary * contextOptions = [NSDictionary DictionaryWithObjectsAndKeys: [NSNumber numberWithBool: flag ],kCIContextUseSoftwareRenderer,nil]; return [CIContext contextWithCGContext: cgContext options: contextOptions]; } - person Kevin Gross; 02.11.2010
comment
Извините... Я понятия не имею, как указать, что комментарий является фрагментом кода. - person Kevin Gross; 02.11.2010
comment
Как ты это используешь? Это работает просто отлично. Получите NSGraphicsContext*, где вы собираетесь визуализировать CIImage, получите соответствующий CIContext с помощью функции выше и вызовите методы CIContext для рисования изображения. Это обычный способ рендеринга на процессоре с помощью CoreImage, он описан в документации Apple и должен работать нормально. - person Gobra; 02.11.2010

Вот версия Swift:

func coreContextFor(context : CGContext,forceSoftware force : Bool) -> CIContext {
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let options : [String:AnyObject] = [
        kCIContextWorkingColorSpace: colorSpace!,
        kCIContextOutputColorSpace : colorSpace!,
        kCIContextUseSoftwareRenderer : NSNumber(bool: force)
    ]

    return CIContext(CGContext: context, options: options)
}
person CryingHippo    schedule 27.03.2016

Не ответ, но вы всегда можете переписать CIkernel как функцию, которая работает со значением RGB пикселя, а затем применить эту функцию в цикле к unsigned char [] данным изображения и преобразовать результат в CIImage.

person Agnius Vasiliauskas    schedule 10.10.2010