Byłą przeźroczystość - teraz PÓŁprze

0

Witam.
Wczoraj w poście poruszyłem temat <ort>przeźroczystości </ort>forma/komponentu. Otóż mimo, że użyłem niesorecyzowanego określenia to otrzymałem kilka wskazówek, które mi się przydadzą w budowie programu.
http://4programmers.net/Forum/viewtopic.php?id=47296
To omawiany post.

Jednak nie stworzenie forma, o różnych kształtach miało być moim celem. :) Chodziło mi o efekt, nazwałem go, półprzeźroczystością.
Chodiz zatem o to, aby dany form/komponent miał kolor (lub jak kto woli - maskę) koloru np. czerwonego, lecz żeby PRZEŚWITYWAŁ przezeń element pulpitu i innych programów. Takie coś można zaobserwować w programie FlashGet. Chodzi mi o ten form symbolizujący postęp. Każdy zapewne wie o co chodzi :-)

Jeśli ktoś wie jak taki efekt uzyskać proszę o odpowiedź. Mile widziany komponent, ale szczerze wolałbym sam się nauczyć tego efektu. Problem w tym, że jestem początkującym i trzebaby mi to bardzo jasno wytłumaczyć. :D

POzdrawiam.

0

Hej!
Odpowiedź wydaje się prosta... Ale nie wiem jak w praktyce... Czy na pewno o to Ci chodzi [???]
Możesz ustawić AlphaBlend formy na True i potem AlphaBlendValue na np. 100. Efekt będzie taki jak w okienku FlashGeta :p
[cya]

0

darmowe komponenty: Glassy i StainedGlass

0

haha ale się złożyło Baterman ;)
nasze drogi się teraz skrzyżowały w poszukiwaniu tego samego
(półprzezroczystość)
Zerkaj na moje pytania w forum
http://4programmers.net/Forum/viewtopic.php?id=47290
tam właśnie poradził mi Beemx i inny życzliwy człowiek gdzie
szukać i jakiego komponentu.
Jeszcze tego drugiego nie sprawdzałem nie wiem czy zadziała.
Jak znajdę rozwiązanie albo przy pomocy tego komponentu - a może
własne hmmm.. to wklepie tu kodzik . A i Ty jak coś zerkniesz to
pare słówek tu napisz :))
Gdzieś widziałem coś takiego zrobionego za pomocą ScanLine,
rzutowanie pobranych linii wzajemnie z jednego obrazka i drugiego
na wspólną bitmape hmmm.. chyba coś takiego :-/
Jak coś wyczaję to dam znać..

0

Oto procedura, która rysuje przezroczystą bitmapę na innej:

procedure DrawAlpha(var Background:TBitmap; const Foreground, Mask:TBitmap; X, Y:Integer; Src:TRect);
var
bg, fg, msk:pbytearray;
a, b, t:integer;
alpha:single;
begin
for b:=0 to Src.Bottom-Src.Top-1 do
if b+y<background.Height then
begin
fg:=foreground.ScanLine[b+Src.Top];
bg:=background.ScanLine[b+y];
msk:=mask.ScanLine[b mod mask.Height];
for a:=0 to Src.Right-Src.Left-1 do
if a+x<background.Width then
begin
alpha:=1-(msk[(a mod mask.Width)*3]+msk[(a mod mask.Width)*3+1]+msk[(a mod mask.Width)*3])/765;
if alpha=1 then
begin
bg[a*3+x*3]:=fg[a*3+Src.Left*3];
bg[a*3+x*3+1]:=fg[a*3+Src.Left*3+1];
bg[a*3+x*3+2]:=fg[a*3+Src.Left*3+2];
end;
if (alpha<>1) and (alpha<>0) then
begin
bg[a*3+x*3]:=round(Alpha*fg[a*3+Src.Left*3]+(1-Alpha)*bg[a*3+x*3]);
bg[a*3+x*3+1]:=round(Alpha*fg[a*3+Src.Left*3+1]+(1-Alpha)*bg[a*3+x*3+1]);
bg[a*3+x*3+2]:=round(Alpha*fg[a*3+Src.Left*3+2]+(1-Alpha)*bg[a*3+x*3+2]);
end;  
end;
end;
end;

Src mówi, jaką część Foreground należy wziąć, Mask to bitmapa, na której znajdują się pixele w skali szarości. Reszty chyba się domyślisz. Acha, wszystkie bitmapy są 24bitowe.

0

Sposób z AlphaBlend w ogóle nie działa bo nie posiadam takiej właściwości dla forma, w delphi 5.0 :] Jak się zapoatrzę w nowszą wersję to pewnie będzie działać ;-)

Co do tej gotowej procedurki to nie bardzo wiem jak jej użyć. :/
(mówiłem, że jestem baaaaaaardzo początkujący? :P)

procedure DrawAlpha(var Background:TBitmap; const Foreground, Mask:TBitmap; X, Y:Integer; Src:TRect);

Background - czy to jest bitmapa po której rysujemy?
Foreground - czy może jest nią ta bitmapa? :]
Mask - kumam
X,Y,Src - również kumam

Czy mógłbyś zamieścić jakiś przykładowy listning programu ilustrujący dzialanie procedurki? A może wysłałbyś mi go na meila? [email protected]

Inter : Hehe, zajrzę. :) Mam nadzieję, że jak uda Ci się uzyskać pożądany efekt to powiesz jak to tego doszedłeś? :D

Pozdrowiam wszystkich, któzy się tu udzielają i znoszą moje pytania :-)

0

Inter: sprawdziłem te dwa komponenty od Ciebie (THarmFade, TPicShow). Oba robią coś zupełnie innego. :/ Robią przejście między jednym obrazkiem, a drugim. Mi zupełnie nie o to chodzi.

Chodzi o to, aby np. moja forma najeżdżając nad tło pulpitu, okno startowe windowsa lub każde inne okienko, nie zakrywała go, lecz pokazywała to co jest pod nią, lecz żeby było także widać bitmapę i komponenty, które są na formie.

Niech ktoś mi powie jak wkleić tu na forum obrazek to wam to zilustruje. :-)

Peace.

0

Właściwośc AlphaBlend niedostępną w Delphi 5 mozna ustawić za pomocą takiej procedury:

procedure Trans(hWnd: hwnd; Amount: Byte);
var
  msg: Integer;
begin
  msg := 0;
  if Amount > 0 then
  begin
    msg := GetWindowLong(hwnd, GWL_EXSTYLE);
    msg := msg or WS_EX_LAYERED;
    SetWindowLong (hWnd, GWL_EXSTYLE , msg);
    SetLayeredWindowAttributes (hWnd, 0, Amount, LWA_ALPHA);
  end;
end;

Jako hWnd podajesz uchwyt okna które ma stac sie przeźroczyste ( w Twoim przypadku uchwyt formy czyli np. Form1.Handle), drugi to poziom przeźroczystoci - od 0 (niewidoczne) do 255 (bez przeźroczystości).

0

Witam
po co stosować procedury, fuknkcę

robisz tak, najprostszym sposobem:

na formie klikasz "View as text" i wpisujesz

```delphi AlphaBlend = True AlphaBlendValue = 233 ``` np. forma programu tak wygląda:
object Form1: TForm1
   Left = 192
   Top = 114
   Width = 696
   Height = 480
```delphi AlphaBlend = True AlphaBlendValue = 233 ``` ```delphi Caption = 'Form1' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 end ```

efekt zajedwa....

ShowMessage('Niech Delphi będzie z Tobą'); 

pozdro
już w Delphi 6 działa

0

Niestety sposób z ustawianiem AlphaBlend przy pomocy View as text nie działa!!! :/ Został wygenerowany błąd mówiący o tym, że nie ma takiej właściwości.
Sposobu z procedurką spróbuję jak wrócę ze szkoł :)

Peace.

0

Cześć :))
Widzę coraz większe zainteresowanie może razem coś wydłubiemy :))
Jeszcze nie kumam bo dopiero co wstałem (zarwana nocka) :))
Ale myślę że komponent THarmFade to jest To czego można użyć :))
Właśnie on posiada procedurę do osiągnięcia "półprzezroczystości"
(nie mylić z przezroczystością czyli okrojeniem obrazka o kolor zerowy)
Tylko że skonstruowana jest tak że parametrem tej procedury jest
szybkość przejścia z niewidocznego obrazka na całkowicie widoczny.
Cały pic polega na tym żeby na pewnym etapie zatrzymać realizację tej procedury (wyskoczyć z pętli).
Efektem czego będzie wyświetlenie obrazka w takim stopniu na ile go zrealizowała ta procedura do momentu przerwania.
Ale jest wielkie ALE :)) żyjemy w państwie prawa i grzebanie w cudzym
dorobku nam nie przystoi no... jedynie możemy skorzystać ze źródła THarmFade jako wzorca, by coś napodobę zmajstrowaćj.:))
Przepraszam za długi monolog ale chciałbym jeszcze czymś się podzielić.
Otóż robiłem kiedyś biblioteczkę graficzną pod T Pascala (wys. rozdzielczości Hi kolor) i tam posiadam procedurkę na "półprzezroczystość " nazwaną "Filtruj"
Dumam sobie czy nie dałoby rady cały zamysł z tej procedury przenieść do Delphi. Oczywiście wykluczam instrukcje dotyczące XMS - ale myślałem by je zastąpić w Delphi ScanLine (pobieranie linii) , no i jakoś
resztę przerobić by była "strawna " dla Delphi.
Sam nie jestem orłem ale może ktoś.....

{----------- Rysuje obrazek o okreslonej przezroczystosci ----------------}
PROCEDURE TOBRAZEK.Filtruj(kl,ln:INTEGER;nrFiltra:BYTE;nazwaObiektu:TOBRAZEK;opcja:BOOLEAN);
var
x,y,pozX,pozY,sz,wy :INTEGER; {zmienne pozycji i rozmiarow obrazka}
sL,dL :^tempLineTAB;{zmienne pomocnicze}
p1,p2 :LONGINT; {zmienne dla pixeli}
r,g,b,rr,gg,bb :BYTE;    {zmienne skladowych R,G,B}
Begin
{pobranie obszaru obrazka...}
pozX:=0; pozY:=0; sz:=nazwaObiektu.Szer; wy:=nazwaObiektu.Wys;
if kl+pozX<0 then pozX:=0-kl; {... i poprawianie ewentualnych bledow}
if ln+pozY<0 then pozY:=0-ln;
if kl+sz>Szer then sz:=Szer-kl;
if ln+wy>Wys then wy:=Wys-ln;
if sz<0 then sz:=0;
if wy<0 then wy:=0;
GetMem(sL,sz*Bpp);GetMem(dL,sz*Bpp); {pobiera pamiec na 2 linie}
if pozX<sz then
for y:=pozY to wy-1 do
begin {dla calego obrazu}
 {pobiera linie zrodlowa}
 PrzeniesBlokXMS(nazwaObiektu.Uchwyt,
 POINTER((y*nazwaObiektu.Szer+pozX)*Bpp),0,sL,(sz-pozX)*Bpp);
 {pobiera linie docelowa}
 PrzeniesBlokXMS(Uchwyt,POINTER((pozX+kl+((ln+y)*Szer))*Bpp),0,dL, (sz-pozX)*Bpp);
 {dla kazdego pixela na lini}
 for x:=0 to sz-1-pozX do
 begin
 p1:=0; {zeruje pixel}
 Move(sL^[x*Bpp],p1,Bpp);Move(dL^[x*Bpp],p2,Bpp); {pobiera pixel}
 PobierzRGB(p1,r,g,b);PobierzRGB(p2,rr,gg,bb); {pobiera wartosci R,G,B}
 {ustala ich srednie w odpowiednim zestawieniu %}
 p2:=SzukajRGB((r*nrFiltra div 255)+(rr-rr*nrFiltra div 255),
 (g*nrFiltra div 255)+(gg-gg*nrFiltra div 255),
 (b*nrFiltra div 255)+(bb-bb*nrFiltra div 255));
 Move(p2,dL^[x*Bpp],Bpp); {rysuje pixel}
 end;
 {rysuje zmieniona linie}
 PrzeniesBlokXMS(0,dL,Uchwyt,POINTER((pozX+kl+((ln+y)*Szer))*Bpp),(sz-pozX)*Bpp);
end;
FreeMem(sL,sz*Bpp);FreeMem(dL,sz*Bpp);
if opcja=true then Ekran.PokazujObszar(kl,ln,sz,wy);
End;

//PS. odnośnie Delphi instrukcje do podmiany:
zmienna nrFiltra służy do podawania wartości przezroczystości 0-255
nazwaObiektu.Szer - to będzie odpowiednik Bitmap.Width itd....
PrzeniesBlokXMS - zastąpić poprzez ScanLine
PobierzRGB - tu instrukcja pobierania pixela z Delphi
itd.. itd...
Nie wiem czy ktoś mnie nie wyśmieje ?:-/ ale jeżeli znajdzie się jakaś
osoba chętna to mogłaby na to zerknąć a może nawet zrobić swój komponent w oparciu o tą "ideę"

0

Cze ;)
Powyższy listing napisany w pascalu podaje po "przeróbce" do Delphi
w poście:

http://4programmers.net/Forum/viewtopic.php?id=47296

1 użytkowników online, w tym zalogowanych: 0, gości: 1