Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.06.2011, 01:05   #1
N0iD
Пользователь
 
Аватар для N0iD
 
Регистрация: 05.05.2010
Сообщений: 50
Радость GDIPlus - кисть с alphablend.

Доброго времени суток, друзья. Помогите с примером кода для Delphi как установить значение прозрачности для кисти. Как описано в cтатье и отображено на рисунке №5.
Cпасибо.
N0iD вне форума Ответить с цитированием
Старый 05.06.2011, 14:21   #2
volod3000
Форумчанин
 
Аватар для volod3000
 
Регистрация: 18.12.2008
Сообщений: 266
По умолчанию

Вот почитай , может поможет :

http://www.efg2.com

Примеры :

http://www.efg2.com/Lab/ImageProcessing/Feathering.htm
http://www.efg2.com/Lab/Graphics/Colors/ColorMix.htm

Мало открыть человеку глаза, большинство еще просит указать дорогу и ждет волшебного пенделя.
volod3000 вне форума Ответить с цитированием
Старый 10.06.2011, 00:56   #3
N0iD
Пользователь
 
Аватар для N0iD
 
Регистрация: 05.05.2010
Сообщений: 50
По умолчанию

volod3000, спасибо. Но это выглядит как издевательство)))
посмотри сайт, второй пост. Обрати внимание на автора и на дату камента
N0iD вне форума Ответить с цитированием
Старый 10.06.2011, 01:00   #4
N0iD
Пользователь
 
Аватар для N0iD
 
Регистрация: 05.05.2010
Сообщений: 50
По умолчанию

Мне бы кусочек кода. создание кисти, рисование ей и присвоение цвета с альфа блендом к этой кисти.
N0iD вне форума Ответить с цитированием
Старый 14.07.2011, 00:04   #5
N0iD
Пользователь
 
Аватар для N0iD
 
Регистрация: 05.05.2010
Сообщений: 50
По умолчанию

Вот это бы на понятный язык перевести. помогите.
Для демонстрации подобной техники создадим круглую цветную кисть с переменной прозрачностью, подобную той, которую можно наблюдать в некоторых современных графических редакторах, например, в Photoshop'е. Кстати, пример реализации такой кисти через класс приведён в книге Фень Юаня "Программирование графики для Windows".

Схема наших дальнейших действий будет следующей. Сначала мы создадим объект TBitmap, на котором нарисуем цветной круг. Затем подготовленный таким образом аппаратно-зависимый растр (DDB) преобразуем в аппаратно-независимый (DIB), для того чтобы получить доступ к отдельным пикселам, каждый из которых умножим на альфа-коэффициент. Последний будет определяться в зависимости от условного расположения пиксела по отношению к центру круга. Не забудем одновременно заполнить альфа-канал. И, наконец, сделаем обратное преобразование с растрами: DIB -> DDB. Полученную таким образом кисть мы будем отображать на поверхности формы при движении по ней мышкой с помощью функции AlphaBlend.

Сначала подключим вспомогательные заголовочные файлы:

#include <algorithm>
#include <memory>

В секции private h-файла формы объявим несколько переменных, что позволит нам обращаться к ним из любого обработчика формы:

std::auto_ptr<Graphics::TBitmap>bit map;
int iCenterX, iCenterY, iWidth,iHeight;
bool bBeginDraw;

Поясним конструкцию std::auto_ptr из первой строки. Здесь мы объявляем автоматический указатель на объект Graphics::TBitmap ("smart" pointer). Вся прелесть работы с подобными указателями заключается в том, что нам в дальнейшем нет нужды заботиться об уничтожении переменных, на которые они ссылаются, как приходится делать в случае с обычными динамически создаваемыми переменными. Объявленные таким образом объекты уничтожаются автоматически при выходе за область их определения.

Чтобы иметь возможность работать с подобными "умными" указателями, мы и объявили заголовочный файл memory из STL (стандартная библиотека шаблонов).

Код, отвечающий за создание изображения кисти, разместим в теле конструктора формы. Здесь стоит акцентировать внимание на том факте, что bitmap должен динамически создаваться в инициализирующей части конструктора, а не в его теле.

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner),bitmap(new(Graphics::T Bitmap))
{
....
}
Затем проинициализируем ряд переменных, они потребуются нам в дальнейшем:

bBeginDraw = false;
iWidth = 30;
iHeight = 30;
iCenterX = iWidth>>1;
iCenterY = iHeight>>1;

Далее инициализируем структуру BITMAPINFOHEADER, которая будет использоваться для организации доступа к отдельным пикселам растра (предполагаем для определённости, что формат пиксела 32-битный):

BITMAPINFOHEADER bmiHeader = {sizeof(BITMAPINFOHEADER),0};
bmiHeader.biWidth = iWidth;
bmiHeader.biHeight = iHeight;
bmiHeader.biPlanes = 1;
bmiHeader.biCompression = BI_RGB;
bmiHeader.biBitCount = 32;
N0iD вне форума Ответить с цитированием
Старый 14.07.2011, 00:05   #6
N0iD
Пользователь
 
Аватар для N0iD
 
Регистрация: 05.05.2010
Сообщений: 50
По умолчанию

Зададим размеры изображения кисточки и пиксельный формат растра:

bitmap->Width=iWidth;
bitmap->Height=iHeight;
bitmap->PixelFormat=pf32bit;

Создаём, а затем выбираем в памяти последовательно цвет кисти, тип пера (границы нам не нужны!) и рисуем круг, залитый, например, красным цветом:

bitmap->Canvas->Brush->Color=clRed;
bitmap->Canvas->Pen->Style=psClear;
bitmap->Canvas->Ellipse(0,0,iWidth,iHeight);

Как указывалось выше, нам необходимо получить доступ к отдельным пикселам изображения. Для этого требуется манипулятор контекста устройства экрана, который возвращает функция GetDC:

HDC ScreenDC=::GetDC(0);

Начиная с 32-битных версий Windows, растры выводимых изображений выравниваются по двойному слову. Исходя из этого, вычислим, какое количество байт приходится на одну строку развёртки:

int SrcNumberOfBytesPerRow= (((iWidth * bmiHeader.biBitCount)+31)&~31)>>3;

Теперь определим размер растра в байтах. Для этого будем использовать функцию GDI GetDIBits. Описание её можно найти в справочном файле Win32.hlp, поставляемом вместе с Builder(Delphi). Мы же поясним только сам способ получения, с помощью данной функции, размера растра. Для этого её пятый параметр должен иметь значение NULL. Тогда, после вызова функции, поле biSizeImage структуры BITMAPINFOHEADER будет содержать размер растра.

::GetDIBits(ScreenDC,bitmap->Handle,0,iHeight,
NULL,(BITMAPINFO*)&bmiHeader, DIB_RGB_COLORS);

На всякий случай, застрахуем себя от неожиданного результата и вручную вычислим размер растра - это стандартный приём при проведении подобных операций.

if(bmiHeader.biSizeImage==0)
{
bmiHeader.biSizeImage=SrcNumberOfBy tes PerRow * iHeight;
}

Настало время объявить и динамически создать массив байтов для аппаратно-независимого растра. И в этом случае, опять будем использовать "умные" указатели.

std::auto_ptr<BYTE>pBits(new BYTE[bmiHeader.biSizeImage]);

Для того чтобы проинициализировать вновь созданный массив, в очередной раз воспользуемся функцией GetDIBits, но теперь в качестве пятого параметра используем указатель на сам массив с методом get.

::GetDIBits(ScreenDC,bitmap->Handle,0,iHeight,
pBits.get(),(BITMAPINFO*)&bmiHeader , DIB_RGB_COLORS);

Далее работаем с массивом пикселов аппаратно-независимого растра. Коэффициент альфа будем вычислять в зависимости от расположения отдельного пиксела растра по отношению к центру круга. Здесь нам понадобятся функции, объявленные в файле algorithm: min и max.

Определим вспомогательный указатель на переменную типа BYTE:

BYTE *pPixel=pBits.get();

Выполним двойной цикл, чтобы обработать все пикселы растра.

for(int y = 0;y<iHeight;y++)

{
for(int x = 0;x < iWidth; x++, pPixel += 4)
{
int distance = (int)(sqrt((x-iCenterX) * (x-iCenterX) + (y-iCenterY) * (y-iCenterY))*255/iCenterX);
BYTE alpha=(BYTE) max (min(255- distance, 255), 0);
pPixel[0] = pPixel[0] * alpha/255;
pPixel[1] = pPixel[1] * alpha/255;
pPixel[2]=pPixel[2]*alpha/255;
pPixel[3]=alpha;
}
}
Таким образом, альфа-каналы и пикселы поверхности источника подготовлены для вывода на приёмную поверхность. Осталось преобразовать аппаратно-независимый растр в аппаратно-зависимый. Для этой цели в WinGDI используется функция SetDIBits:

::SetDIBits(ScreenDC,bitmap->Handle,0,iHeight,
pBits.get(),(BITMAPINFO*) &bmiHeader, DIB_RGB_COLORS);

Не забудем освободить ресурс контекста устройства экрана:

::ReleaseDC(0,ScreenDC);
Таким образом, картинка, с помощью которой мы собираемся имитировать нашу кисточку, создана. Осталось запрограммировать сам процесс рисования. Для этого будем использовать три обработчика события компонента TImage, который у нас служит в качестве фона (для разнообразия картинку фона мы сменим): Image1MouseDown, Image1MouseMove, Image1MouseUp.

В тело обработчика Image1MouseDown запишем следующий код:

if (Button == mbLeft) bBeginDraw = true;

То есть, при нажатии левой кнопки мыши, булевая переменная станет равной истине; в нашем случае это даст старт процессу рисования.

Само рисование будет происходить в обработчике Image1MouseMove:

if (bBeginDraw == true)
{
BLENDFUNCTION blend = {AC_SRC_OVER, 0, 200, AC_SRC_ALPHA};
AlphaBlend (Image1->Canvas->Handle, X-iCenterX,Y-iCenterY, iWidth, iHeight, hMem, 0, 0, iWidth, iHeight, blend);
Image1->Repaint();
}

И, наконец, когда левая кнопка мыши отпускается, следует закончить рисование. Для этого в обработчике Image1MouseUp, достаточно поместить следующую строчку:

bBeginDraw = false;
N0iD вне форума Ответить с цитированием
Старый 14.07.2011, 00:06   #7
N0iD
Пользователь
 
Аватар для N0iD
 
Регистрация: 05.05.2010
Сообщений: 50
По умолчанию

кто поможет дам 10 уе = )
N0iD вне форума Ответить с цитированием
Старый 15.07.2011, 18:30   #8
N0iD
Пользователь
 
Аватар для N0iD
 
Регистрация: 05.05.2010
Сообщений: 50
По умолчанию

Нужна кисть такая же как тут. vkontakte.ru/swf/Graffiti.swf
N0iD вне форума Ответить с цитированием
Старый 15.07.2011, 20:33   #9
denisbrain
Форумчанин
 
Регистрация: 29.05.2011
Сообщений: 449
По умолчанию

Цитата:
Сообщение от N0iD Посмотреть сообщение
Нужна кисть такая же как тут. vkontakte.ru/swf/Graffiti.swf
если $10 то код на дельфи
иначе
см
Приём.Blue=alpha* Источн.Blue+(1-alpha)* Приём.Blue
Приём.Green=alpha* Источн.Green+(1-alpha)* Приём.Green
Приём.Red=alpha* Источн.Red+(1-alpha)* Приём.Red
Приём.alpha=alpha* Источн.alpha+(1-alpha)* Приём.alpha
задания на pascal/delphi ICQ 368254335
Tel +79177425326 mail denis-naymov1985(at)mail.ru login skype denis.new.skype
denisbrain вне форума Ответить с цитированием
Старый 16.07.2011, 13:05   #10
denisbrain
Форумчанин
 
Регистрация: 29.05.2011
Сообщений: 449
По умолчанию

не правильный пост...
задания на pascal/delphi ICQ 368254335
Tel +79177425326 mail denis-naymov1985(at)mail.ru login skype denis.new.skype

Последний раз редактировалось denisbrain; 16.07.2011 в 14:24.
denisbrain вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Использование AlphaBlend askarchic Общие вопросы Delphi 11 25.03.2011 13:34
AlphaBlend и onResize D][mon Помощь студентам 0 29.09.2010 22:06
Можно ли, используя перо и кисть( в делфи)) нарисовать параллелограмм? vedro-compota Мультимедиа в Delphi 7 05.06.2010 20:16
Image и AlphaBlend Zeraim Общие вопросы Delphi 4 09.09.2009 12:45
AlphaBlend + ShowModal Cardagant Общие вопросы Delphi 2 11.06.2008 15:42