Можно ли создать подобный эффект для Paint?NET? Конечно, возможно.
Итак, начнем шаг за шагом.
Шаг 1. Откройте какое-либо изображение. Добавьте новый слой.
Шаг 2. Примените к слою эффект Облака со следующими параметрами: Приближение - 24, Жесткость - 0.40.
Шаг 3. В меню Коррекция запустите эффект Кривые (Коррекция -> Кривые). Левую нижнюю точку кривой перетащите вправо до середины, установив ее значения в (127,0). Правую верхнюю точку кривой перетащите влево до середины, установив ее значения в (128,255).
Шаг 4. Устраните светлые участки слоя, применив эффект Устранить темный/светлый.
Шаг 5. В меню Слои выберите Свойства слоя. В открывшемся диалоговом окне выберите режим смешивания Умножение или Замена темным, установите непрозрачность слоя в 25.
Ниже показан получившийся результат:
Сравните с предыдущим рисунком. Похоже, не правда ли? Попробуйте повторить предыдущие действия для разных параметров Приближение и Жесткость эффекта Облака и непрозрачности слоя.
Теперь давайте будем создавать наш эффект. Запустите CodeLab (Эффекты -> Advanced -> Code Lab). В меню Файл выберите Новый. Выберите в выпадающем списке эффектов Облака, в выпадающем списке Режимы смешивания выберите Умножение или Замена темным. Нажмите кнопку Генерировать код. Мы получим следующий сценарий эффекта:
Код: Выделить всё
#region UICode
int Amount1 = 250; // [2,1000] Приближение
double Amount2 = 0.5; // [0,1] Четкость
BinaryPixelOp Amount3 = LayerBlendModeUtil.CreateCompositionOp(LayerBlendMode.Normal); // Режим смешивания
byte Amount4 = 0; // [255] Перегенерировать
#endregion
// Настройки для вызова обработки эффекта Облака
private CloudsEffect cloudsEffect = new CloudsEffect();
private PropertyCollection cloudsProps;
// Настройки для использования режима смешивания Умножение
private BinaryPixelOp multiplyOp = LayerBlendModeUtil.CreateCompositionOp(LayerBlendMode.Multiply);
// Это основной цикл функции обработки
void Render(Surface dst, Surface src, Rectangle rect)
{
// Вызов обработки функции Облака
cloudsProps = cloudsEffect.CreatePropertyCollection();
PropertyBasedEffectConfigToken CloudsParameters = new PropertyBasedEffectConfigToken(cloudsProps);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Scale, Amount1);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Power, Amount2);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.BlendMode, Amount3);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Seed, (int)Amount4);
cloudsEffect.SetRenderInfo(CloudsParameters, new RenderArgs(dst), new RenderArgs(src));
// Вызов функции Облака с использованием черного и белого цветов
cloudsEffect.Render(new Rectangle[1] {rect},0,1);
// Теперь в основном цикле холст назначения (dst) обработан облаками
for (int y = rect.Top; y < rect.Bottom; y++)
{
if (IsCancelRequested) return;
for (int x = rect.Left; x < rect.Right; x++)
{
ColorBgra CurrentPixel = dst[x,y];
// ВЫПОЛНЕНИЕ: Добавьте здесь дополнительный код обработки пикселей
CurrentPixel = multiplyOp.Apply(src[x,y], CurrentPixel);
dst[x,y] = CurrentPixel;
}
}
}
Закомментируйте или удалите следующую строку:
Код: Выделить всё
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.BlendOp, Amount3);
В строке
Код: Выделить всё
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Seed, (int)Amount4);
Так как мы изменили тип переменной Amount2, нам придется внести измения в следующую строку
Код: Выделить всё
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Power, Amount2);
Сохраните этот сценарий с именем Sponge_1 (Файл -> Сохранить). Создайте одноименный DLL файл, проверьте как он работает. Итак, мы воспроизвели шаг 2, описанный выше.
Теперь давайте создадим аналог шага 3. Для этого нам понадобятся переменные R, G, B и A. Добавим их в наш сценарий:
Код: Выделить всё
CurrentPixel = dst[x,y];
int R = CurrentPixel.R;
int G = CurrentPixel.G;
int B = CurrentPixel.B;
int A = CurrentPixel.A;
Код: Выделить всё
// Преобразование в контрастное черно-белое изображение
if (R<128) {R=0;}
else R=255;
if (G<128) {G=0;}
else G=255;
if (B<128) {B=0;}
else B=255;
Код: Выделить всё
CurrentPixel.R = Int32Util.ClampToByte(R);
CurrentPixel.G = Int32Util.ClampToByte(G);
CurrentPixel.B = Int32Util.ClampToByte(B);
Код: Выделить всё
A = 255 - Math.Min(Math.Min(R,G),B);
Код: Выделить всё
CurrentPixel.A = Int32Util.ClampToByte(A + Amount3 - 255);
Код: Выделить всё
#region UICode
int Amount1 = 25; // [2,100] Размер кисти
int Amount2 = 0; // [0,10] Шероховатость
int Amount3 = 255; // [0,255] Интенсивность
#endregion
// Настройки для вызова обработки эффекта Облака
private CloudsEffect cloudsEffect = new CloudsEffect();
private PropertyCollection cloudsProps;
// Настройки для использования режима смешивания Умножение
private BinaryPixelOp multiplyOp = LayerBlendModeUtil.CreateCompositionOp(LayerBlendMode.Multiply);
// Это основной цикл функции обработки
void Render(Surface dst, Surface src, Rectangle rect)
{
// Вызов обработки функции Облака
cloudsProps = cloudsEffect.CreatePropertyCollection();
PropertyBasedEffectConfigToken CloudsParameters = new PropertyBasedEffectConfigToken(cloudsProps);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Scale, Amount1);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Power, Amount2/10.0);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Seed, 255);
cloudsEffect.SetRenderInfo(CloudsParameters, new RenderArgs(dst), new RenderArgs(src));
// Вызов функции Облака с использованием черного и белого цветов
cloudsEffect.Render(new Rectangle[1] {rect},0,1);
// Теперь в основном цикле холст назначения (dst) обработан облаками
for (int y = rect.Top; y < rect.Bottom; y++)
{
if (IsCancelRequested) return;
for (int x = rect.Left; x < rect.Right; x++)
{
ColorBgra CurrentPixel = dst[x,y];
// ВЫПОЛНЕНИЕ: Добавьте здесь дополнительный код обработки пикселей
CurrentPixel = dst[x,y];
int R = CurrentPixel.R;
int G = CurrentPixel.G;
int B = CurrentPixel.B;
int A = CurrentPixel.A;
// Преобразование в черно-белое контрастное изображение
if (R<128) {R=0;}
else R=255;
if (G<128) {G=0;}
else G=255;
if (B<128) {B=0;}
else B=255;
CurrentPixel.R = Int32Util.ClampToByte(R);
CurrentPixel.G = Int32Util.ClampToByte(G);
CurrentPixel.B = Int32Util.ClampToByte(B);
// Устранение светлых участков
A = 255 - Math.Min(Math.Min(R,G),B);
CurrentPixel.A = Int32Util.ClampToByte(A + Amount3 - 255);
CurrentPixel = multiplyOp.Apply(src[x,y], CurrentPixel);
dst[x,y] = CurrentPixel;
}
}
}
Ниже приведены диапазоны параметров нашего эффекта, наиболее соответствующие результатам работы фильтра Губка в Фотошопе:
- Размер кисти - 22...32
- Шероховатость - 0...10
- Интенсивность - 10...55
Давайте внесем изменения в наш сценарий с учетом полученных результатов.
Блок кода интерфейса пользователя будет выглядеть так:
Код: Выделить всё
#region UICode
int Amount1 = 2; // [0,10] Размер кисти
int Amount2 = 7; // [0,10] Шерховатость
int Amount3 = 5; // [0,15] Интенсивность
#endregion
Код: Выделить всё
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Scale, Amount1 + 20);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Power, 1.0 - Amount2/10.0);
Код: Выделить всё
CurrentPixel.A = Int32Util.ClampToByte(A + Amount3*3 - 255);
Код: Выделить всё
// Author: ReMake
// Submenu: Artistic
// Name: Губка
// Title: Губка
// Desc: Paint.Net эффект, имитирующий рисование губкой
// Keywords: paint.net|эффект|губка
// URL: http://www.getpaint.net/redirect/plugins.html
Код: Выделить всё
// Author: ReMake
// Submenu: Artistic
// Name: Губка
// Title: Губка
// Desc: Paint.Net эффект, имитирующий рисование губкой
// Keywords: paint.net|эффект|губка
// URL: http://www.getpaint.net/redirect/plugins.html
#region UICode
int Amount1 = 2; // [0,10] Размер кисти
int Amount2 = 7; // [0,10] Шерховатость
int Amount3 = 5; // [0,15] Интенсивность
#endregion
// Настройки вызова обработки эффекта Облака
private CloudsEffect cloudsEffect = new CloudsEffect();
private PropertyCollection cloudsProps;
// Настройки использования режима смешивания Умножение
private BinaryPixelOp multiplyOp = new UserBlendOps.MultiplyBlendOp();
// Это основной цикл функции обработки
void Render(Surface dst, Surface src, Rectangle rect)
{
// Вызов функции обработки Облака
cloudsProps = cloudsEffect.CreatePropertyCollection();
PropertyBasedEffectConfigToken CloudsParameters = new PropertyBasedEffectConfigToken(cloudsProps);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Scale, Amount1 + 22);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Power, 1.0 - Amount2/10.0);
CloudsParameters.SetPropertyValue(CloudsEffect.PropertyNames.Seed, 255);
cloudsEffect.SetRenderInfo(CloudsParameters, new RenderArgs(dst), new RenderArgs(src));
// Вызов функции Облака с использованием черного и белого цветов
cloudsEffect.Render(new Rectangle[1] { rect }, 0, 1);
//ColorBgra PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
// Теперь в основном цикле холст назначения (dst) обработан облаками
for (int y = rect.Top; y < rect.Bottom; y++)
{
if (IsCancelRequested) return;
for (int x = rect.Left; x < rect.Right; x++)
{
ColorBgra CurrentPixel = dst[x, y];
// ВЫПОЛНЕНИЕ: Добавьте здесь код обработки пикселей
CurrentPixel = dst[x,y];
int R = CurrentPixel.R;
int G = CurrentPixel.G;
int B = CurrentPixel.B;
int A = CurrentPixel.A;
// Преобразование в черно-белое контрастное изображение
if (R<128) {R=0;}
else R=255;
if (G<128) {G=0;}
else G=255;
if (B<128) {B=0;}
else B=255;
CurrentPixel.R = Int32Util.ClampToByte(R);
CurrentPixel.G = Int32Util.ClampToByte(G);
CurrentPixel.B = Int32Util.ClampToByte(B);
// Устранение светлых участков
A = 255 - Math.Min(Math.Min(R,G),B);
CurrentPixel.A = Int32Util.ClampToByte(A + Amount3*3 - 245);
CurrentPixel = multiplyOp.Apply(src[x, y], CurrentPixel);
dst[x, y] = CurrentPixel;
}
}
}
Теперь давайте сохраним наш эффект как DLL файл: Файл -> Сохранить как DLL... В представленном вам диалоге сборки DLL есть почти вся необходимая информация. Щелкните по ссылке Выбор значка и выберите ваш значок. Нажмите кнопку Создать - ваш новый эффект готов!
Так выглядит интерфейс пользователя нашего нового эффекта.
А так выглядит результат работы эффекта.
Я думаю, что создание этого эффекта затруднений у вас не вызвало.
P.S. Для того, чтобы результат работы этого эффекта был максимально пхож на работу фотошоповского фильтра Губка, сначала примените к изображению эффект Картина, масло с параметрами: Размер кисти - 2...3 и Грубость мазков - 3... 20.
Результат работы обоих эффектов выглядит так:
К сожалению одновременное использование двух встроенных Paint.Net эффектов в CodeLab недоступно.