Делаем эффект для рисования окружности

Эта ветка форума посвящена вопросу, как самому сделать свой плагин (эффект) для Paint.NET. Для публикации своих эффектов используйте основной форум "Эффекты и плагины к Paint.NET"
Ответить
Аватара пользователя
xmario
Администратор
Сообщения: 3402
Зарегистрирован: 03 апр 2010, 20:12
Репутация: 45
Пол: Мужской
Откуда: Москва

Делаем эффект для рисования окружности

Сообщение xmario » 25 апр 2010, 16:37

Делаем собственный плагин для Paint.NET - Эффект для рисования окружности.

Написание этого урока основано на вопросе одного из участников этого форума Vasy111, который справедливо поинтересовался, как в Paint.NET нарисовать окружность с явным указанием её радиуса.

Нарисовать круг и окружность в Paint.NET любого радиуса несложно с помощью инструмента «фигуры». Размер окружности при рисовании указывается в строке состояния Paint.NET. Тем не менее, указать радиус окружности в явном виде, с клавиатуры нет.

Что же, устраним эту проблему на этом уроке, а заодно еще раз попрактикуемся в написании плагинов и дополнительных эффектов к Paint.NET. Как обычно, для того, что бы сделать свой плагин к Paint.NET, используем CodeLab. Для тех, кто не в курсе, на форуме есть специальная ветка "Что такое CodeLab от BoltBait". Итак, будем делать плагин, который рисует круг или окружность.

Пойдем от простого к сложному и сначала сделаем эффект (плагин) для Paint.NET, который рисует круг. Для рисования круга нам нужны следующие данные:
  • Радиус круга – пусть пользователь задает его самостоятельно.
  • Цвет, которым будем рисовать круг – пусть это будет основной цвет, указанный в палитре 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
нам понадобится только одна, которая будет обозначать выбор радиуса круга. Напишем эту строку так:

Код: Выделить всё

int Amount1=50;	//[1,500]Внешний радиус круга
Значение по умолчанию мы установили 50, а интервал изменения радиуса от 1 до 500.
Строки учебного скрипта, отвечающие за дополнительный цвет и размер кисти, нам не нужны, поэтому эти строки можно удалить.

Код: Выделить всё

    ColorBgra SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
    int BrushWidth = (int)EnvironmentParameters.BrushWidth;
Закомментированные строки действия скрипта, устанавливающие цвет пикселя как основной надо раскомментировать, потому что это именно то, что должен делать наш скрипт.

Код: Выделить всё

            CurrentPixel.R = (byte)PrimaryColor.R;
            CurrentPixel.G = (byte)PrimaryColor.G;
            CurrentPixel.B = (byte)PrimaryColor.B;
            CurrentPixel.A = (byte)PrimaryColor.A;
Однако, если теперь выполнить наш скрипт, то основным цветом будет заполнен весь холст, а не круг, все потому что мы не указали условие нашего круга.
Откроем учебник по геометрии и вспомним, что уравнение окружности имеет вид

(x-CenterX)*(x-CenterX)+(y-CenterY)*(y-CenterY)) = R*R

Где CenterX – это ордината центра окружности по оси X, а CenterY – это ордината центра окружности по оси Y и, наконец, R – радиус окружности, который в нашем скрипте находится в переменной Amount1.

Таким образом условие нашего скрипта будет таким:

Код: Выделить всё

if (((x-CenterX)*(x-CenterX)+(y-CenterY)*(y-CenterY))-Amount1*Amount1 <= 0)
А весь скрипт теперь выглядит так:

Код: Выделить всё

#region UICode
int Amount1=50;	//[1,500]Внешний радиус круга
#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 CurrentPixel;
    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        for (int x = rect.Left; x < rect.Right; x++)
        {
            CurrentPixel = src[x,y];
            if (((x-CenterX)*(x-CenterX)+(y-CenterY)*(y-CenterY))-Amount1*Amount1 <= 0)
            {
            // 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;
            }
            else
            {
            dst[x,y] = CurrentPixel;
            }
        }
    }
}
Вот результат

Изображение

Можно немного модернизировать наш скрипт, добавив еще один параметр внутренний радиус и немного изменив условие. В этом случае можно будет с помощью созданного нами плагина рисовать не только круги, но и окружности. Причем окружности с разной толщиной линии.

Изображение

Вот код модернизированного скрипта.

Код: Выделить всё

#region UICode
int Amount1=50;	//[1,500]Внешний радиус круга
int Amount2=40;	//[1,500]Внутренний радиус круга
#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 CurrentPixel;
    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        for (int x = rect.Left; x < rect.Right; x++)
        {
            CurrentPixel = src[x,y];
            if (
                (((x-CenterX)*(x-CenterX)+(y-CenterY)*(y-CenterY))-Amount1*Amount1 <= 0)
                &&
                (((x-CenterX)*(x-CenterX)+(y-CenterY)*(y-CenterY))-Amount2*Amount2 >= 0)
               )
            {
            // 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;
            }
            else
            {
            dst[x,y] = CurrentPixel;
            }
        }
    }
}
Изображение

Так должен выглядеть получившейся на уроке эффект.

Ну а для тех, кому не особо интересно создание собственных плагинов, те могут скачать скомпилированный плагин для Paint.NET из этого урока с расширенными возможностями в отдельной теме этого форума. После установки эффект доступен в меню "Эффекты" - "Узоры" - "Рисование окружности".
Для тех, кто не знает, здесь можно прочитать "Как устанавливать эффекты и плагины в paint.net".

Ответить

Вернуться в «Как сделать свой эффект (плагин) для Paint.NET»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 10 гостей