Этот урок представляет собой интерпретацию на русском языке англоязычного урока от автора плагина CodeLab под ником BoltBait. Исходный текст урока на английском языке можно найти здесь.
Итак, в качестве первого плагина Paint.NET мы будем создавать эффект, который рисует в Paint.NET точку в центре выделенной области.
Для создания собственного эффекта мы используем плагин CodeLab, описанию которого посвящена отдельная тема на этом форуме viewtopic.php?f=13&t=61.
Для начала создадим в Paint.NET новое изображение небольшого размера. Например, 9 на 9 пикселей. Лучше нечетное число, т.к. нам нужен будет центр. И увеличим его масштаб раз в пять, например 1200. Иначе, особенно на большом разрешении монитора можно не увидеть результат действия нашего первого эффекта. Как вы понимаете, создаваемый нами эффект носит скорее учебный характер, чем имеет какое-то практическое применение.
Итак, открываем эффект CodeLab. Изначально окно редактирования скрипта в CodeLab уже содержит текст учебного скрипта по умолчанию.
Немного теории. Принцип действия большинства эффектов и скриптов заключается в том, что они в большинстве своем содержат цикл, в котором эффект «пробегают» (перебирает, проходит) по всем пкселам выделенной в Paint.NET области и совершает какие-то действия с ними.
Авторы эффектов применяют два термина холст источник – это то изображение, которое вы видите на экране до выполнения какого-либо эффекта. И холст назначения – это то, изображение, которое получится после выполнения эффекта. Именно на холсте назначения мы и будем совершать действия над пикселами.
Вышеописанный принцип - получение исходной информации с хослта источника и перенос ее с использованием алгоритмов на холст назначения применяется практически во всех эффектах. Есть сложные эффекты, например, стандартный эффект Paint.NET «набросок тушью», а есть очень простые, типа, «точка в центре», который мы и будем сейчас делать.
Как уже упоминалось выше эффект CodeLab уже содержит текст учебного скрипта по умолчанию. Этот учебный скрипт пробегает все точки выделенной области холста источника и копирует их, без каких либо изменений, на холст назначения. Т.е. по сути ничего не делает. Точнее визуально результата у этого скрипта нет, потому что то, что было равно тому, что стало.
Тем не менее на примере этого скрипта сделаем наш эффект точка в центре. Вот текст учебного скрипта.
Код: Выделить всё
#region UICode
int Amount1=0; //[0,100]Slider 1 Description
int Amount2=0; //[0,100]Slider 2 Description
int Amount3=0; //[0,100]Slider 3 Description
#endregion
void Render(Surface dst, Surface src, Rectangle rect)
{
// Delete any of these lines you don't need
Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
long CenterX = (long)(((selection.Right - selection.Left) / 2)+selection.Left);
long CenterY = (long)(((selection.Bottom - selection.Top) / 2)+selection.Top);
ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
int BrushWidth = (int)EnvironmentParameters.BrushWidth;
ColorBgra CurrentPixel;
for (int y = rect.Top; y < rect.Bottom; y++)
{
for (int x = rect.Left; x < rect.Right; x++)
{
CurrentPixel = src[x,y];
// TODO: Add pixel processing code here
// Access RGBA values this way, for example:
// CurrentPixel.R = (byte)PrimaryColor.R;
// CurrentPixel.G = (byte)PrimaryColor.G;
// CurrentPixel.B = (byte)PrimaryColor.B;
// CurrentPixel.A = (byte)PrimaryColor.A;
dst[x,y] = CurrentPixel;
}
}
}
Код: Выделить всё
int Amount1=0; //[0,100]Slider 1 Description
int Amount2=0; //[0,100]Slider 2 Description
int Amount3=0; //[0,100]Slider 3 Description
Нам не нужен дополнительный цвет и не нужна толщина кисти. Поэтому две строки, приведенные ниже тоже можно удалить.
Код: Выделить всё
ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
int BrushWidth = (int)EnvironmentParameters.BrushWidth;
Код: Выделить всё
long CenterX = (long)(((selection.Right - selection.Left) / 2)+selection.Left);
long CenterY = (long)(((selection.Bottom - selection.Top) / 2)+selection.Top);
Код: Выделить всё
if ((y == CenterY) && (x == CenterX))
Код: Выделить всё
CurrentPixel.R = (byte)PrimaryColor.R;
CurrentPixel.G = (byte)PrimaryColor.G;
CurrentPixel.B = (byte)PrimaryColor.B;
CurrentPixel.A = (byte)PrimaryColor.A;
Код: Выделить всё
void Render(Surface dst, Surface src, Rectangle rect)
{
// Delete any of these lines you don't need
Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
long CenterX = (long)(((selection.Right - selection.Left) / 2)+selection.Left);
long CenterY = (long)(((selection.Bottom - selection.Top) / 2)+selection.Top);
ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
ColorBgra CurrentPixel;
for(int y = rect.Top; y < rect.Bottom; y++)
{
for (int x = rect.Left; x < rect.Right; x++)
{
CurrentPixel = src[x,y];
// TODO: Add pixel processing code here
if ((y == CenterY) && (x == CenterX))
{
// Access RGBA values this way, for example:
CurrentPixel.R = (byte)PrimaryColor.R;
CurrentPixel.G = (byte)PrimaryColor.G;
CurrentPixel.B = (byte)PrimaryColor.B;
CurrentPixel.A = (byte)PrimaryColor.A;
}
dst[x,y] = CurrentPixel;
}
}
}
Обратите внимание, что функция Render вашего эффекта выполняется Paint.NET несколько раз. Paint.NET разбивает выделенную область изображения на несколько квадратиков, которые обычно называют рабочими областями. Для каждой рабочей области выполняется ваша функция Render. Для чего это сделано? Для оптимизации работы. Особенно это заметно на двух и четырех ядерных процессорах.
Ну и результат в виде рисунка здесь.