Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.05.27;
Скачать: CL | DM;

Вниз

draw transparent bitmap   Найти похожие ветки 

 
novi4ek   (2012-01-24 00:01) [0]

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

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

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

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 секунды, я не успею с громоздким кодом.
может есть какой простой вариант без маски?


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

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

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.. но пока ещё етсаь надежда найти простой выход...


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


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

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


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

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

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

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 вроде бы рисуется прозрачно, но где-то светлит..


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

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


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

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

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

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


 
RWolf ©   (2012-01-24 10:16) [6]

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


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


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

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


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

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

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

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

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


 
RWolf ©   (2012-01-25 01:03) [9]

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


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

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


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

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


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

Ужас.


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



Страницы: 1 вся ветка

Текущий архив: 2012.05.27;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.009 c
2-1327379649
de_guta
2012-01-24 08:34
2012.05.27
Проблема с TIdHttp


2-1327473823
дикий
2012-01-25 10:43
2012.05.27
Вопрос по установке размеров страницы при печати


15-1326904284
Gu
2012-01-18 20:31
2012.05.27
Xe2U4


2-1327400950
Григорий
2012-01-24 14:29
2012.05.27
помогите разобраться с кодом


2-1326976172
3asys
2012-01-19 16:29
2012.05.27
рисование поверх документов