Что необходимо знать прежде, чем записать пользовательский фильтр
OS X предоставляет поддержку для записи пользовательских фильтров. Пользовательский фильтр один, для которого Вы пишете подпрограмму, названную ядром, указывающим вычисления для выполнения на каждом пикселе исходного изображения. Если Вы планируете использовать встроенные Базовые фильтры Изображения, или как они или путем разделения на подклассы их, Вы не должны читать эту главу. Если Вы планируете записать пользовательский фильтр, необходимо считать эту главу, таким образом, Вы понимаете путь обработки и компоненты в пользовательском фильтре. После чтения этой главы можно узнать, как записать фильтр в Создании Пользовательских Фильтров. Если Вы интересуетесь упаковкой Вашего пользовательского фильтра для распределения, необходимо также считать Упаковку и Загрузку Модулей Изображения.
Отфильтруйте клиенты и отфильтруйте создателей
Базовое Изображение разработано для двух типов разработчиков: отфильтруйте клиенты и отфильтруйте создателей. Если Вы планируете только использовать Базовые фильтры Изображения, Вы - клиент фильтра. Если Вы планируете записать свой собственный фильтр, Вы - создатель фильтра.
Рисунок 8-1 показывает компоненты типичного фильтра. Заштрихованная область числа указывает части, которые являются “под капотом” — части, о которых клиент фильтра ничего не должен знать, но который должен понять создатель фильтра. Часть это не заштриховывается, показывает два метода —attributes
и outputImage
— это предоставляет данные клиенту фильтра. Фильтр attributes
метод возвращает список пар ключ/значение, описывающих фильтр. outputImage
метод производит использование изображения:
Сэмплер для выборки пикселей из источника
Ядро, обрабатывающее пиксели
В основе каждого пользовательского фильтра ядро. Ядро указывает вычисления, выполняющиеся на каждом пикселе исходного изображения. Вычисления ядра могут быть очень простыми или сложными. Очень простое ядро для “делает ничто” не фильтрует, мог просто возвратить исходный пиксель:
destination pixel = source pixel
Отфильтруйте использование создателей вариант Языка Штриховки OpenGL (glslang) для указания вычислений на пиксель. (См. Базовую Ссылку Языка Ядра Изображения.) Ядро непрозрачно клиенту фильтра. Фильтр может фактически использовать несколько подпрограмм ядра, передавая вывод одного к вводу другого. Для получения инструкций по тому, как записать пользовательский фильтр, посмотрите Создающие Пользовательские Фильтры.
Создатели фильтра могут сделать свои пользовательские фильтры доступными для любого приложения путем упаковки их как плагина или отобразить модуль, с помощью архитектуры, указанной NSBundle
класс. Модуль изображения может содержать больше чем один фильтр, как показано на рисунке 8-2. Например, Вы могли записать ряд фильтров, выполняющих различные виды граничного обнаружения и упаковывающих их как единственный модуль изображения. Клиенты фильтра могут использовать Базовое Изображение API, чтобы загрузить модуль изображения и получить список фильтров, содержавшихся в том модуле изображения. Посмотрите Загружающиеся Модули Изображения для основной информации. См. Учебное руководство по Модулю Изображения для всесторонних примеров и подробной информации о записи фильтров и упаковке их как автономные модули изображения.
Путь обработки
Рисунок 8-3 показывает пиксельный путь обработки для фильтра, воздействующего на два исходных изображения. Исходные изображения всегда указываются как CIImage
объекты. Базовое Изображение обеспечивает множество способов получить данные изображения. Можно предоставить URL к изображению, считать необработанные данные изображения (использующий NSData
класс), или преобразовывают Кварц 2D изображение (CGContextRef
), текстура OpenGL или Базовый буфер Видеоизображения (CVImageBufferRef
) к a CIImage
объект.
Обратите внимание на то, что фактическое число входных изображений, и требует ли фильтр входного изображения, зависит от фильтра. Фильтры очень гибки — фильтр может:
Работа без входного изображения. Некоторые фильтры генерируют изображение на основе входных параметров, которые не являются изображениями. (Например, посмотрите
CICheckerboardGenerator
иCIConstantColorGenerator
просачивается Базовая Ссылка Фильтра Изображения.)Потребуйте одного изображения. (Например, посмотрите
CIColorPosterize
иCICMYKHalftone
просачивается Базовая Ссылка Фильтра Изображения.)Потребуйте двух или больше изображений. Фильтры, составляющие изображения или использующие значения в одном изображении, чтобы управлять, как пиксели в другом изображении обрабатываются обычно, требуют двух или больше изображений. Одно входное изображение может действовать как изображение штриховки, маска изображения, фоновое изображение, или обеспечить источник справочных значений, управляющих некоторым аспектом того, как обрабатывается другое изображение. (Например, посмотрите
CIShadedMaterial
просочитесь Базовая Ссылка Фильтра Изображения.)
При обработке изображения это - ответственность создать a CIImage
объект, содержащий надлежащие входные данные.
Пиксели из каждого исходного изображения выбираются a CISampler
объект, или просто сэмплер. Как его имя предполагает, сэмплер получает выборки изображения и обеспечивает их для ядра. Создатель фильтра обеспечивает сэмплер для каждого исходного изображения. Клиенты фильтра ничего не должны знать о сэмплерах.
Сэмплер определяет:
Координатное преобразование, которое может быть идентификационными данными, преобразовывает, если не необходима никакая трансформация.
Режим интерполяции, который может быть самым близким соседом, выбирающим или билинейной интерполяцией (который является значением по умолчанию).
Переносящийся режим, указывающий, как произвести пиксели, когда выбранная область за пределами исходного изображения — или для использования прозрачного черного цвета или зажима до степени.
Создатель фильтра определяет вычисления обработки изображений на пиксель в ядре, но Базовое Изображение обрабатывает фактическую реализацию тех вычислений. Базовое Изображение определяет, выполняются ли вычисления с помощью GPU или CPU. Базовое Изображение реализует аппаратную растеризацию через OpenGL на OS X и через OpenGLES на iOS. Это реализует растеризацию программного обеспечения через среду эмуляции, в частности настроенную для оценки программ фрагмента с непроективными поисками текстуры по большим четырехугольникам (четверки).
Несмотря на то, что пиксельный путь обработки от исходного изображения до места назначения, путь вычисления, который Базовое использование Изображения начинает в месте назначения и работает его путь назад к исходным пикселям, как показано на рисунке 8-4. Это обратное вычисление могло бы казаться громоздким, но оно фактически минимизирует число пикселей, используемых в любом вычислении. Альтернатива, которую не использует Базовое Изображение, является методом грубой силы обработки всех исходных пикселей, тогда более позднего решения, что необходимо для места назначения. Давайте бросим более внимательный взгляд на рисунок 8-4.
Предположите, что фильтр на рисунке 8-4 выполняет некоторую работу составления композита, такую как источник - по составлению композита. Клиент фильтра хочет перекрыть два изображения так, чтобы только небольшая часть каждого изображения была составлена для достижения результата, показанного в левой стороне рисунка 8-4. Путем предвидения то, каково место назначения должно быть, Базовое Изображение может определить, какие данные из исходных изображений влияют на заключительное изображение и затем ограничивают вычисления только теми исходными пикселями. В результате сэмплеры выбирают демонстрационные пиксели только от заштрихованных областей в исходных изображениях, показанных на рисунке 8-4.
Отметьте поле на рисунке 8-4, который это маркировало Доменом определения. Домен определения является просто способом далее ограничить вычисления. Это - область, за пределами которой все пиксели прозрачны (т.е. альфа-компонент равен 0). В этом примере домен определения совпадает точно с конечным изображением. Базовое Изображение позволяет Вам предоставить a CIFilterShape
объект определить эту область. CIFilterShape
класс обеспечивает много методов, которые могут определить прямоугольные формы, преобразовать формы и выполнить вставку, объединение и перекрестные операции на формах. Например, если Вы определяете форму фильтра с помощью прямоугольника, который меньше, чем заштрихованная область, показанная на рисунке 8-4, затем Базовое Изображение использует ту информацию для дальнейшего ограничения исходных пикселей, используемых в вычислении.
Базовое Изображение способствует эффективной обработке другими способами. Это выполняет интеллектуальное кэширование и оптимизацию компилятора, делающую его подходящим для таких задач как обработка видео реального времени и анализ изображения. Это кэширует промежуточные результаты для любого набора данных, неоднократно оценивающегося. Базовое Изображение выселяет данные в последнем использованном порядке, добавляя, что новое изображение заставило бы кэш становиться слишком большим. Объекты, снова использующиеся часто, остаются в кэше, в то время как используемые время от времени могли бы быть перемещены в и из кэша по мере необходимости. Ваше приложение получает преимущества от Базового Изображения, кэширующегося, не будучи должен знать подробные данные того, как реализовано кэширование. Однако Вы получаете лучшую производительность путем многократного использования объектов (изображения, контексты, и т.д) каждый раз, когда Вы можете.
Базовое Изображение также получает высокую эффективность при помощи традиционных методов компиляции на уровнях передачи и ядре. Использование Изображения Ядра метода для выделения регистров минимизирует число временных регистров (на ядро) и временные пиксельные буферы (на граф фильтров). Компилятор выполняет несколько оптимизации и автоматически различает чтение информационно-зависимых текстур, основывающихся на предыдущих вычислениях, и тех, которые не информационно-зависимы. Снова, Вы не должны интересоваться подробными данными методов компиляции. Важный момент - то, что Базовое Изображение является аппаратным здравым смыслом; это использует питание GPU и многожильного CPUs каждый раз, когда это может, и это делает так умными способами.
Координатные пространства
Базовое Изображение выполняет операции в независящей от устройств рабочей области. Базовая рабочая область Изображения, в теории, бесконечной в степени. Точка в рабочей области представлена координатной парой (x, y), где x представляет расположение вдоль горизонтальной оси, и y представляет расположение вдоль вертикальной оси. Координаты являются значениями с плавающей точкой. По умолчанию источник является точкой (0,0).
Когда Базовое Изображение читает изображение, оно переводит пиксельные расположения в независящие от устройств координаты рабочей области. Когда пора вывести на экран обработанное изображение, Базовое Изображение переводит координаты рабочей области в надлежащие координаты для места назначения, такие как дисплей.
Когда Вы пишете свои собственные фильтры, необходимо быть знакомы с двумя координатными пространствами: пространство координаты назначения и пространство сэмплера. Пространство координаты назначения представляет изображение, к которому Вы представляете. Пространство сэмплера представляет то, что Вы текстурируете от (другое изображение, таблица поиска, и т.д.). Вы получаете текущее расположение в целевом пространстве с помощью destCoord
функционируйте тогда как samplerCoord
функция обеспечивает текущее расположение в выборочном пространстве. (См. Базовую Ссылку Языка Ядра Изображения.)
Следует иметь в виду, что, если Ваши исходные данные размещается рядом, координаты сэмплера имеют смещение (dx/dy). Если Ваши демонстрационные координаты имеют смещение, может быть необходимо для Вас преобразовать целевое расположение в расположение сэмплера с помощью функции samplerTransform
.
Область интереса
Несмотря на то, что не явно маркированный на рисунке 8-4, заштрихованная область в каждом из исходных изображений является представляющей интерес областью для сэмплеров, изображенных в числе. Область интереса или ROI, определяет область в источнике, из которого сэмплер берет информацию о пикселе для обеспечения для ядра для обработки. Если Вы - клиент фильтра, Вы не должны интересоваться ROI. Но если Вы будете создателем фильтра, то Вы захотите понять отношение между областью интереса и доменом определения.
Вспомните, что домен определения описывает форму ограничения фильтра. В теории эта форма может быть без границ. Рассмотрите, например, фильтр, создающий повторяющийся образец, который мог расшириться на бесконечность.
ROI и домен определения могут коснуться друг друга следующими способами:
Они совпадают точно — существует 1:1 отображающийся между источником и местом назначения. Например, фильтр оттенка обрабатывает пиксель от координаты рабочей области (r, s) в ROI для создания пикселя в координате рабочей области (r, s) в домене определения.
Они зависят друг от друга, но модулируемые в некотором роде. Некоторые самые интересные фильтры — размытость и искажение, например — используют много исходных пикселей в вычислении одного целевого пикселя. Например, фильтр искажения мог бы использовать пиксель (r, s) и его соседи от рабочего координатного пространства в ROI для создания единственного пикселя (r, s) в домене определения.
Домен определения вычисляется от значений в таблице поиска, которые предоставлены сэмплером. Расположение значений в карте или таблице не связано с координатами рабочей области в исходном изображении и месте назначения. Значение, расположенное в (r, s) в изображении штриховки, не должно быть значением, производящим пиксель в координате рабочей области (r, s) в домене определения. Много фильтров используют значения, предоставленные в изображении штриховки или таблице поиска в сочетании с источником изображения. Например, шкала цветов или таблица, приближающая функцию, такой как
arcsin
функционируйте, обеспечивает значения, которые не связаны с понятием рабочих координат.
Если иначе не проинструктировано, Базовое Изображение предполагает, что совпадают ROI и домен определения. Если Вы пишете фильтр, для которого это предположение не содержит, необходимо предоставить Базовому Изображению подпрограмму, вычисляющую ROI для определенного сэмплера.
Посмотрите Предоставление Функции ROI для получения дополнительной информации.
Исполнимые и неисполнимые фильтры
Можно категоризировать пользовательские Базовые фильтры Изображения на основе того, требуют ли они, чтобы вспомогательная двоичная исполнимая программа была загружена в адресное пространство клиентского приложения. Поскольку Вы используете Базовое Изображение API, Вы заметите, что они просто упоминаются как исполнимая программа и неисполнимая программа. Создатели фильтра могут принять решение записать любой вид фильтра. Клиенты фильтра могут принять решение использовать только неисполнимую программу или использовать оба вида фильтров.
Безопасность является основной мотивацией для различения исполнимой программы CPU и неисполнимых фильтров CPU. Неисполнимые фильтры состоят только из Базовой программы ядра Изображения для описания работы фильтра. Напротив, исполнимый фильтр также содержит машинный код, работающий на CPU. Базовые программы ядра Изображения, выполненные в ограниченной среде и, не могут изобразить из себя вирус, Троянского коня или другую угрозу нарушения безопасности, тогда как произвольный код, работающий на CPU, может.
Неисполнимые фильтры имеют особые требования, одно из которых - то, что неисполнимые фильтры должны быть упакованы как часть модуля изображения. Создатели фильтра могут считать Неисполнимые Фильтры Записи для получения дополнительной информации. Клиенты фильтра могут найти информацию о загрузке, каждый отчасти просачивается Загружающиеся Модули Изображения.
Компоненты цвета и предварительно умноженная альфа
Предварительно умноженная альфа является термином, использованным для описания исходного цвета, компоненты которого были уже умножены на альфа-значение. Предварительное умножение ускоряет рендеринг изображения, избавляя от необходимости выполнить работу умножения для каждого компонента цвета. Например, в цветовом пространстве RGB, представляя изображение с предварительно умноженной альфой устраняет три операции умножения (красная альфа времен, зеленая альфа времен и синяя альфа времен) для каждого пикселя в изображении.
Создатели фильтра должны предоставить Базовое Изображение компоненты цвета, предварительно умножающиеся на альфа-значение. Иначе, фильтр ведет себя, как будто альфа-значение для компонента цвета 1.0. Компоненты цвета проверки предварительно умножаются, важно для фильтров, управляющих цветом.
По умолчанию Базовое Изображение предполагает, что процессорные узлы составляют 128 бит на пиксель, линейный свет, предварительно умножил значения с плавающей точкой RGBA, использующие цветовое пространство GenericRGB. Можно указать различное рабочее цветовое пространство путем обеспечения Кварца 2D объект CGColorSpace. Обратите внимание на то, что рабочее цветовое пространство должно быть основано на RGB. Если у Вас есть данные YUV, как введено (или другие данные, которые не основаны на RGB), можно использовать функции ColorSync для преобразования в рабочее цветовое пространство. (См. Кварц 2D Руководство по программированию для получения информации о создании и использовании объекты CGColorspace.)
С 8-разрядным YUV 4:2:2 источники, Базовое Изображение может обработать 240 уровней HD на гигабайт. Восьмиразрядный YUV является собственным цветным форматом для источника видеосигнала, такого как DV, MPEG, распаковал D1 и JPEG. Необходимо преобразовать цветовые пространства YUV в цветовое пространство RGB для Базового Изображения.
См. также
Shantzis, Майкл A., “Модель для эффективных и гибких вычислений изображения”, (1994), продолжения 21-й ежегодной конференции по вопросам компьютерной графики и интерактивных методов.
Смит, Альви Рэй, “основные принципы составления композита изображения”, уведомление 4, Microsoft, июль 1995. Доступный от http://alvyray.com/Memos/MemosCG.htm#ImageCompositing