Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

draw transparent bitmap


novi4ek ©   (2012-01-24 00:01:00) 

подскажите пожалуйста, только начинаю изучать..

есть канвас. необходимо на нем отрисовать с прозрачным фоном мой битмап.

пытаюсь что - то такое:

bkColor:= GetBkColor(Canvas.Handle);

SetBkColor(Canvas.Handle, myTransparentColor);
SetBkMode(Canvas.Handle, TRANSPARENT);

BitBlt(Canvas.Handle, 0, 0, OverlayBMP.Width, OverlayBMP.Height, OverlayBMP.Canvas.Handle, 0, 0, SRCCOPY);

подскажите, есть ли какие стандартные функции что бы учитывали TRANSPARENT цвет и не отрисовывали бы?

пока нахожу варианты с использованием маски.. но у меня битмап должен выводится каждые 1\25 секунды, я не успею с громоздким кодом.
может есть какой простой вариант без маски?


Псарь   (2012-01-25 23:06:00) [1]

Ужас.


 Bitmap.Transparent:= True;
 Bitmap.Draw(X, Y, Canvas);


Sapersky   (2012-01-25 18:42:00) [2]

Применительно к битмапам, чтобы что-то там ускорилось, нужно их создавать как DDB. При этом теряем доступ к пикселям и возможность нарисовать что-то вручную, а GDI по спецэффектам бедноват.
Да и по факту более-менее заметное ускорение я заметил только с BitBlt на XP (TransparentBlt - всего процентов на 30).
На Win7 DDB даёт некоторое даже замедление.
В общем, для нормального аппаратного ускорения нужны DX/OGL, на GDI в этом плане надежды мало.


han_malign   (2012-01-25 09:35:00) [3]

- для особо ленивых есть ImageList, который и маску по опорному цвету сгенерирует, и три-блит сделает...


RWolf   (2012-01-25 01:03:00) [4]

Правильные драйвера должны использовать для операций вроде BitBlt аппаратное ускорение вывода битмапов в видеопамять.


Sapersky   (2012-01-24 21:16:00) [5]

и вообще странно, откуда появляются такие монстры процедуры, как  DrawTransparentBitmap...

Изначально в GDI не было функции вывода с прозрачным цветом, отсюда извращения.
Потом добавили - TransparentBlt, но мало кто об этом знал (в стандартных хелпах к старым Дельфи её нет), к тому же в Win98 она глючила. Сейчас, конечно, можно 98-й не учитывать.

вы серьёзно думаете, что попиксельная закраска быстрее BitBlt?

GDI вообще-то неидеален... тот же прозрачный цвет при рисовании в 32-битный битмап получается раза в 2 быстрее, чем TransparentBlt.
Подозреваю, что GDI сравнивает цвет покомпонентно, а можно как одно 32-битное число. Если альфа мешается - отрезать её and-ом с маской.
Аналогично можно отрезать лишнее у 24-битного цвета, но там получается плохое выравнивание (адреса, по которым берутся данные, не кратны 4), поэтому эффект меньше - 1.5 раза.


Андреевич   (2012-01-24 10:17:00) [6]


> и вообще странно, откуда появляются такие монстры процедуры,
>  как  DrawTransparentBitmap..
> разве что для наглядности что бы понять суть..

это когда не хочется заморачиваться со сканлайном, и форматом. Ну и BitBlt() все таки быстрее сканлайна, хоть и значительно меньше с ним возможностей по рисованию.
могу свой пример дать, вот тут http://forum.sources.ru/index.php?showtopic=241930прикрепленный файл.
Но еще лучше перейти на альфаканал :)


RWolf   (2012-01-24 10:16:00) [7]

вы серьёзно думаете, что попиксельная закраска быстрее BitBlt?


u4enik   (2012-01-24 03:57:00) [8]

вообщем остановился на самостоятельной прорисовке через массив цветов, в моём случаи 24 бита, - array of TRGBTriple.

проверил по времени, прорисовка, если установить черную подложку через BitBlt, что-то в районе 2.0E-8, если самому перебирать буфер цветов, где-то 3.0Е-8.   но BitBlt прозрачно отрисует только на черной подложке, плюс цвета изменит, т.к. там через OR вроде бы идет прорисовка..
может в gdi32 есть что ещё, но я все же остановился на своём варианте..

и вообще странно, откуда появляются такие монстры процедуры, как  DrawTransparentBitmap..
разве что для наглядности что бы понять суть..


u4enik   (2012-01-24 00:52:00) [9]

вот BitBlt с параметром SRCPAINT отрисовывает всё кроме черного.
как можно задать свой цвет вместо черного?


u4enik   (2012-01-24 00:43:00) [10]

думаете? вроде бы сканлайн быстро воркает..
я вот  тут пока нашел тестовый выход..

у меня есть канвас только..
я создаю битмап

bmp:= TBitmap.Create;
bmp.Width  :=  CanvasWidth;
bmp.Height :=  CanvasHeight;
bmp.Canvas.Handle:= Canvas.handle;
bmp.PixelFormat:= CanvasPixelFormat;

теперь вроде бы мне уже доступно

bmp.TransparentColor:= myTransparentColor;

ну а далеее пока что думаю.. )

BitBlt(bmp.Canvas.Handle, 0, 0, BMP.Width, BMP.Height, OverlayBMP.Canvas.Handle, 0, 0, SRCPAINT);

при черном myTransparentColor вроде бы рисуется прозрачно, но где-то светлит..


antonn   (2012-01-24 00:29:00) [11]


> уже подумываю через scanLine поцветно переносить битмап
> на канвас учитывая transparent.. но пока ещё етсаь надежда
> найти простой выход...

будет не менее громоздко :)


u4enik   (2012-01-24 00:06:00) [12]

часто встречаю эту процедуру:

procedure DrawTransparentBitmap(Cnv: TCanvas; x,y: Integer; Bmp: Graphics.TBitmap; clTransparent: TColor);
var
 bmpXOR, bmpAND, bmpINVAND, bmpTarget: Graphics.TBitmap;
 oldcol: Longint;
begin
 try
   bmpAND := Graphics.TBitmap.Create;
   bmpAND.Width := Bmp.Width;
   bmpAND.Height := Bmp.Height;
   bmpAND.Monochrome := True;
   oldcol := SetBkColor(Bmp.Canvas.Handle, ColorToRGB(clTransparent));
   BitBlt(bmpAND.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, Bmp.Canvas.Handle, 0, 0, SRCCOPY);
   SetBkColor(Bmp.Canvas.Handle, oldcol);

   bmpINVAND := Graphics.TBitmap.Create;
   bmpINVAND.Width := Bmp.Width;
   bmpINVAND.Height := Bmp.Height;
   bmpINVAND.Monochrome := True;
   BitBlt(bmpINVAND.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, bmpAND.Canvas.Handle, 0, 0, NOTSRCCOPY);

   bmpXOR := Graphics.TBitmap.Create;
   bmpXOR.Width := Bmp.Width;
   bmpXOR.Height := Bmp.Height;
   BitBlt(bmpXOR.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, Bmp.Canvas.Handle, 0, 0, SRCCOPY);
   BitBlt(bmpXOR.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, bmpINVAND.Canvas.Handle, 0, 0, SRCAND);

   bmpTarget := Graphics.TBitmap.Create;
   bmpTarget.Width := Bmp.Width;
   bmpTarget.Height := Bmp.Height;
   BitBlt(bmpTarget.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, Cnv.Handle, x, y, SRCCOPY);
   BitBlt(bmpTarget.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, bmpAND.Canvas.Handle, 0, 0, SRCAND);
   BitBlt(bmpTarget.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, bmpXOR.Canvas.Handle, 0, 0, SRCINVERT);
   BitBlt(Cnv.Handle, x, y, Bmp.Width, Bmp.Height, bmpTarget.Canvas.Handle, 0, 0, SRCCOPY);
 finally
   FreeAndNil(bmpXOR);
   FreeAndNil(bmpAND);
   FreeAndNil(bmpINVAND);
   FreeAndNil(bmpTarget);
 end;
end;

но это же ужос как громоздко..
неужели нет никаких попроще вариантов?

уже подумываю через scanLine поцветно переносить битмап на канвас учитывая transparent.. но пока ещё етсаь надежда найти простой выход...


Наверх

Титульная страница Поиск, карта сайта Написать письмо