Вот беглая версия, которую я сделал, что это «больше» в реальное время (Это запись с сим, устройство (6с) является гладким в зависимости от исходного размера изображения.

Создать . один ViewController IOS приложение из шаблона и добавить UIImageView и три ползунка на раскадровку, так это выглядит, как живой GIF
Я создал простой класс для хранения значений ColorCtrl (яркость, контрастность, насыщенность:
public class ColorCtrl
{
public float s;
public float b;
public float c;
}
чем в методе ViewDidLoad
, сделать некоторые настройки:
public override void ViewDidLoad()
{
base.ViewDidLoad();
string filePath = Path.Combine (NSBundle.MainBundle.BundlePath, "hero.jpg");
originalImage = new CIImage (new NSUrl (filePath, false));
colorCtrls = new CIColorControls();
colorCtrls.Image = originalImage;
// Create the context only once, and re-use it
var contextOptions = new CIContextOptions();
contextOptions.UseSoftwareRenderer = false; // gpu vs. cpu
// On save of the image, create a new context with highqual attributes and re-apply the filter...
contextOptions.HighQualityDownsample = false;
contextOptions.PriorityRequestLow = false; // high queue order it
contextOptions.CIImageFormat = (int)CIFormat.ARGB8; // use 32bpp, vs. 64|128bpp
context = CIContext.FromOptions (contextOptions);
}
Тогда для обработчиков изменить три ползунка.
Внутри этих я «взломаю» флаг занятости, чтобы пропустить преобразование изображения, если последнее преобразование не выполнено. Если мы не заняты, тогда вызовите вызов нашего метода преобразования async.
Примечание: Я сказал: «взломать», я имею в виду это, в наилучшей практике, как это должно перекачивать преобразование запросов в очереди и обработчик очереди будет суммировать все ожидающие элементов в очереди, промойте их и сделать преобразование.
Примечание. Я добавил «асинхронный вызов» к сгенерированным обработчикам событий, чтобы преобразовать изображение в await
.
Примечание. Обработчики трех ползунков являются одинаковыми, за исключением значения, которое они назначают; colorCtrlV.b | colorCtrlV.s | colorCtrlV.c
Примечание: Вы можете вниз образец большое изображение на данный момент пользователь не приземление, выполнять преобразования на этом, и на ощупь вверх, преобразование оригинального полноразмерного изображения ...
async partial void brightnessChange (UISlider sender)
{
if (!busy) {
busy = true;
colorCtrlV.b = sender.Value;
this.imageView.Image = await FilterImageAsync (colorCtrlV);
busy = false;
}
}
Итак, теперь для фактического преобразования достаточно простая Run.Task, чтобы мы могли выполнить эту работу с основного потока и НЕ блокировать пользовательский интерфейс. Таким образом, слайдеры не будут заикаться, поскольку пользователь скользит пальцем, НО из-за «загруженного» флага/взлома в обработчике слайдера мы можем пропустить некоторые из этих событий (мы должны должно добавить обработчик для касания перетаскивания, чтобы мы обработать «последнее» запрошенное пользователем значение ....)
// async Task.Run() - not best practice - just a demo
async Task<UIImage> FilterImageAsync (ColorCtrl value)
{
if (transformImage == null)
transformImage = new Func<UIImage>(() => {
colorCtrls.Brightness = colorCtrlV.b;
colorCtrls.Saturation = colorCtrlV.s;
colorCtrls.Contrast = colorCtrlV.c;
var output = colorCtrls.OutputImage;
var cgImage = context.CreateCGImage (output, originalImage.Extent);
var filteredImage = new UIImage (cgImage);
return filteredImage;
});
UIImage image = await Task.Run<UIImage>(transformImage);
return image;
}
Лично Для этого типа в реальном времени преобразования изображения я предпочитаю делать это с помощью OpenGL-ES с помощью GPUImage как взаимодействие экрана со скоростью обновления 60Z так гладко, как сливочное масло, но это намного больше чем использование фильтров CoreImage
.
Выполнение этого способа, вероятно, приведет к тому, что HandleValue изменится так, чтобы его вызывали несколько раз одновременно, вызывая сбои. Если вы добавите какую-то логику для предотвращения параллельного выполнения этого метода, она, вероятно, будет работать лучше. – Jason
Спасибо Джейсону. Ваш отзыв заставил меня экспериментировать и придумать что-то не слишком далеко от принятого ответа ниже. –