|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
05.06.2011, 14:21 | #2 |
Форумчанин
Регистрация: 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 Мало открыть человеку глаза, большинство еще просит указать дорогу и ждет волшебного пенделя. |
10.06.2011, 01:00 | #4 |
Пользователь
Регистрация: 05.05.2010
Сообщений: 50
|
Мне бы кусочек кода. создание кисти, рисование ей и присвоение цвета с альфа блендом к этой кисти.
|
14.07.2011, 00:04 | #5 |
Пользователь
Регистрация: 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; |
14.07.2011, 00:05 | #6 |
Пользователь
Регистрация: 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; |
14.07.2011, 00:06 | #7 |
Пользователь
Регистрация: 05.05.2010
Сообщений: 50
|
кто поможет дам 10 уе = )
|
15.07.2011, 18:30 | #8 |
Пользователь
Регистрация: 05.05.2010
Сообщений: 50
|
Нужна кисть такая же как тут. vkontakte.ru/swf/Graffiti.swf
|
15.07.2011, 20:33 | #9 |
Форумчанин
Регистрация: 29.05.2011
Сообщений: 449
|
если $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 |
16.07.2011, 13:05 | #10 |
Форумчанин
Регистрация: 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. |
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Использование 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 |