Кто-нибудь знает, как указать основному образу обрабатывать CIImage через CIFilter с использованием ЦП вместо графического процессора? Мне нужно обработать несколько очень больших изображений, и я получаю странные результаты при использовании графического процессора. Меня не волнует, сколько времени потребуется, чтобы процессор был в порядке.
Как обрабатывать CIFilter, используя CPU вместо GPU?
Ответы (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 в своих приложениях и всегда делаю рендеринг с помощью графического процессора на экране, в то время как принудительный процессор используется только для сохранения. Я заметил, что рендеринг процессора на моем тестовом оборудовании немного точнее, а сохранение отфильтрованного изображения — долгий процесс, здесь я могу пожертвовать скоростью.
Вот версия 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)
}
Не ответ, но вы всегда можете переписать CIkernel как функцию, которая работает со значением RGB пикселя, а затем применить эту функцию в цикле к unsigned char []
данным изображения и преобразовать результат в CIImage.