Форум paint.net на русском языке

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

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

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

Сообщение 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»

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

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

добавить на Яндекс
Rambler's Top100
Нравится

Этот сайт посвящен всему, что связано с бесплатным графическим редактором paint.net и вообще с рисованием в целом. На этом сайте вы найдете уроки paint.net, эффекты и плагины paint.net и даже просто схемы рисования, по которым можно рисовать обычными красками и простым карандашом. А вообще в интернет можно найти много интересного. Например, детям игры для детей или где найти образец резюме. И еще много того, что может оказаться полезным.