Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2012.05.27;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.003 c
2-1327267176
shaman
2012-01-23 01:19
2012.05.27
ini файл


2-1327425569
sem
2012-01-24 21:19
2012.05.27
Вызов процедуры


9-1191912113
bioSerg
2007-10-09 10:41
2012.05.27
Возникла проблема с Direct3d на новых карточках ATI x2000


2-1327379649
de_guta
2012-01-24 08:34
2012.05.27
Проблема с TIdHttp


2-1327326974
Faceless
2012-01-23 17:56
2012.05.27
помогите определиться с входными параметрами в функции сортировки





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский