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

Вниз

32 битные битмапы с альфой на TSpeedButton   Найти похожие ветки 

 
VS   (2009-12-08 10:56) [0]

ДОбрый день. Столкнулся с небольшой проблемой.. необходимо вывести 32битные битмапы на кнопки. SpeedButton.Glyph чтобы то есть рисовался красиво, прям ух))

Как то не особо давно antonn выкладывал на этом форуме приятную процедуру для рисования 32 битных битмапов с альфой.

procedure BlendBitmap_GDI(ACanvas: TCanvas; BT:Tbitmap; x,y:integer);
const
MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
type
PRGBAArray = ^TRGBAArray;
TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var xTo,sx,YTo,ddx,ddy,sy,w,h,dstw,dsth: integer;
  bt_buff:Tbitmap; i,ii,itemp:integer; RSource,RDest:PRGBAArray; dd:double;
begin

if bt.PixelFormat<>pf32bit then Exit;

w:=BT.Width;
h:=bt.Height;
dstw:=ACanvas.ClipRect.Right-ACanvas.ClipRect.Left;
dsth:=ACanvas.ClipRect.Bottom-ACanvas.ClipRect.Top;
XTo:=x+W-1; YTo:=y+H-1;
if (y>=dstH) or (x>=dstW) or (YTo<0) or (XTo<0) then exit;
ddx:=0; ddy:=0;
sx:=W; sy:=H;

if X<0 then
begin
 ddx:=-X;
 inc(sx,X);
 x:=0;
end;

if Y<0 then
begin
 ddy:=-Y;
 inc(sy,Y);
 y:=0;
end;

if XTo>=dstw then dec(sx,XTo-dstw+1);
if YTo>=dsth then dec(sy,YTo-dsth+1);
if (sx<=0) or (sy<=0) then exit;

bt_buff:=Tbitmap.Create;
try
  bt_buff.Width:=sx;
  bt_buff.Height:=sy;
  bt_buff.canvas.CopyRect( rect(0,0,bt_buff.Width,bt_buff.Height), ACanvas ,rect(x,y,x+sx,y+sy) );
  bt_buff.PixelFormat:=pf32bit;
  for i:=0 to sy-1 do begin
    RSource:=BT.ScanLine[i+ddy];
    RDest:=bt_buff.ScanLine[i];
    for ii:=0 to sx-1 do begin
      dd:=(1/255)*RSource[ii+ddx].rgbReserved;

      itemp:=round(RDest[ii].rgbRed+(RSource[ii+ddx].rgbRed-RDest[ii].rgbRed)*dd);
      if itemp>255 then itemp:=255 else if itemp<0 then itemp:=0;
      RDest[ii].rgbRed:=itemp;

      itemp:=round(RDest[ii].rgbGreen+(RSource[ii+ddx].rgbGreen-RDest[ii].rgbGreen)*dd);
      if itemp>255 then itemp:=255 else if itemp<0 then itemp:=0;
      RDest[ii].rgbGreen:=itemp;

      itemp:=round(RDest[ii].rgbBlue+(RSource[ii+ddx].rgbBlue-RDest[ii].rgbBlue)*dd);
      if itemp>255 then itemp:=255 else if itemp<0 then itemp:=0;
      RDest[ii].rgbBlue:=itemp;
    end;
  end;
  ACanvas.CopyRect( rect(x,y,x+sx,y+sy), bt_buff.canvas ,rect(0,0,bt_buff.Width,bt_buff.Height) );
finally
  bt_buff.Free;
end;
end;


Эта процедура чудесно рисует 32 битные битмапы, поэтому решив себя сильно не запаривать, я подумал что можно отрисовать битмапы на кнопках при помощи этой процедуры. Без особой боли в сердце я изъял из VCL Buttons.pas (переименовав его и подключив к своему проекту) и заместо тамошней отрисовки кнопки  
TButtonGlyph(FGlyph).Draw(Canvas, PaintRect, Offset, Caption, FLayout, FMargin, FSpacing, FState, Transparent, DrawTextBiDiModeFlags(0));
я начал рисовать этой процедурой. Кнопочки стали как картинки, такие аккуратненькие, и радовали мой глаз, но недолго.. Все было бы хорошо,
если бы не одна не особо приятная вещь, которая начала твориться. Кнопки перерисовывались только после того, как мышью по ним проведешь, ну или после любого другого действия, которое приводит к перерисовке. То есть если затащишь форму с такой кнопко за пределы экрана, а потом вытащишь обратно, то картинка пропадает. Навел мышку или сресайзил форму - и картинка появилась.

Тогда я решил использовать Windows.AlphaBlend()
Проблема пропала, картинки с кнопок не исчезают, все приятно.. но не радует глаз, потому что Windows.AlphaBlend менее красивую картинку выдает.

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

Сердцем чую, что проблема в процедуре BlendBitmap_GDI.
Ибо даже когда с ее помощью выводишь на вкладки PageControl-a рисунки, то они также затираются.
Но никак не могу понять из-за какого криминального места происходит сие поведение. Прошу помощи.


 
clickmaker ©   (2009-12-08 13:21) [1]

> то они также затираются

они наверно не затираются, а просто не отрисовываются
TButtonGlyph(FGlyph).Draw вызывается в четырех местах


 
VS   (2009-12-08 13:42) [2]

Я в 1м посте облажался, не то написал слегка, но смысл тот же.
TButtonGlyph(FGlyph).Draw вызывает TButtonGlyph.DrawButtonGlyph и вот там я закомментил ThemeServices.DrawIcon(Canvas.Handle, Details, R, FGlyphList.Handle, Index); и отрисовал Glyph процедурой BlendBitmap_GDI

Непонятно все равно поведение, почему Windows.AlphaBlend в том же самом месте пишешь и ничего не стирается, а BlendBitmap_GDI заместо него пишешь - кнопки не перерисовываются.

Ну проблема ведь в этой процедуре (почти на 100% уверен), потому что также я при помощи этой процедуры рисую на TVirtualDrawTree, и также, как и с кнопками, после того как затащишь форму за пределы экрана - картинки пропадают, до момента вызова процедуры перерисовки. И на PageControl-e та же хрень.


 
VS   (2009-12-09 07:47) [3]

Не, народ, я конечно понимаю, что можно подряд вызвать 2 процедуры рисования, последняя из которых будет BlendBitmap_GDI, но ведь это некрасивое решение, хотя визуально практически незаметно когда какой процедурой отрисовано (имею ввиду кто не знает - не заметит). Но ведь это неправильный "выход" из ситуации. У кого-нибудь есть идеи?



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

Форум: "Начинающим";
Текущий архив: 2010.01.31;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.007 c
4-1228146698
Пётр
2008-12-01 18:51
2010.01.31
Список окон Alt+Tab


3-1234091593
Booo
2009-02-08 14:13
2010.01.31
Ошибка


15-1258961960
Palladin
2009-11-23 10:39
2010.01.31
Простенький NAT сервер под Windows XP


2-1260359041
webpauk
2009-12-09 14:44
2010.01.31
Рекурсивная функция и уровень рекурсии


2-1260278642
Danco
2009-12-08 16:24
2010.01.31
Поместить картинку из TWebBrowser в TImage





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский