Przezroczysta forma z PNG

0

Cześć. Szukałem szukałem i nie wyszukałem, a mianowicie mam forme na której jest obrazem PNG + efekty Alpha Channel. Chce zrobić przezroczystą formę na której będzie ten obrazek wraz z cieniami itp. Jedyne rozwiązanie jakie na razie znalazłem to Brush.Style := bsClear, które działa znakomicie, <ort>do pÓÓÓÓki </ort>jakieś okno nie najedize mi na formę :/ Czy ktoś zna jakiś sposób na to lub komponent? Dodam, że nie chodzi mi o bitmapy i zabawę z regionami bo to ma być jeden obrazek PNG, który ma już swoje efekty (cień, przezroczystość). Z góry dzięki i pozdro ;)

0

Sprowadź sobie plik PNG do 32bitowej bitmapy, a potem zamień swoje okno na 'layered window' (patrz Win SDK). W sieci można znaleźć moduł alphaeffects, tam masz przykład czegoś podobnego (tylko bez wykorzystania PNG).

0

Konwertując PNG do BMP obrazek chyba nie zachowa swoich własności w postaci cieniów i przezroczystości kolorów ;)

PS.: Nie ma sposobu, żeby odświeżyć ten bsClear? Przeszukałem połowę Internetu i nic :( Chyba zostanie mi tylko ręczne rysowanie Canvasem bo to taki Splash Screen :/

0
Andre napisał(a)

Konwertując PNG do BMP obrazek chyba nie zachowa swoich własności w postaci cieniów i przezroczystości kolorów ;)

Mówiłem o bitmapie 32bitowej :P

Andre napisał(a)

PS.: Nie ma sposobu, żeby odświeżyć ten bsClear?

Ale Ty w końcu chcesz, żeby forma brała (pół)przezroczystość z pliku PNG, czy jak? zmiana pędzla formy na bsclear tu chyba niewiele daje? :P</quote>

0

spróbuj tego:

SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
SetLayeredWindowAttributes(Handle, Kolor_przezroczystości, 0 , LWA_COLORKEY);
0

Pokaże to na przykładzie:

Tworze formę o wymiarach obrazka który jest na dole. Kłade na nią Image a w nim ten obrazek (PNG widać, że obrazek ma cienie). W OnCreate formy daje Form1.Brush.Style := bsClear i BorderStyle na None. Podczas uruchomienia wszystko jest tak jak chce, to znaczy wyświetla mi się obrazek z pełną obsługą PNG z Alpha Channelem na ekranie. Dodam, że forma (jej nie widać) jest zawsze na wierzchu. Wszystko by było ok, jakby nie to, że wystarczy, że byle jakie okno najedzie na moją formę (tzn. obrazek) i na formie zostaje po tym ślad. Stąd chcę się dowiedzieć jak można odświeżyć wtedy formę, albo znaleźć jakiś komponent, który będzie działał lepiej od bsClear. Mam nadzieję, że teraz wszystko jest zrozumiałe :)

user image - obrazek

user image - forma po kompilacji

user image - forma po najechaniu na nią jakeigoś okna :/

0
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
SetLayeredWindowAttributes(Handle, ColorToRGB(clBtnFace), 0 , LWA_COLORKEY);

to u mnie załatwia sprawę - bo sprawdziłem

0

Dziwne, dałem to w OnCreate i powstało takie coś zamiast cienia: :(

user image

0

Obrazek masz w TImage

0

sprobuj raczej nie z OnCreate, ale OnPaint, moze pomoze ;)

0

Dałem Timer'a na 3 sekundy, po których ma włączyć się ta procedura, jednak to nic nie dało, efekt podobny jak na obrazku wyżej :/

http://images3.fotosik.pl/21/ka64wbnqxtdpiji4.png

0

Ja mam tak:
Obrazek w TImage Transparent:= True;

onCreate robie:

SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
SetLayeredWindowAttributes(Handle, ColorToRGB(clBtnFace), 0 , LWA_COLORKEY);

i jest. Mam delphi 7 oraz PNGImage.

0

Hmm, chyba brakuje mi komponentu targa, ale tak czy siak jak sie przyrzysz to ta procka usuwa cień, czyli odpada :/

user image

0

A może byś się tak przyjrzał temu modułowi alphaeffects, co?
http://www.am-ende.net/delphi/alphaeffects/

0

Patrzyłem, ale to działa na 2 bitmapach i maskach, czego ja chciałem uniknąć :(

0
Andre napisał(a)

Patrzyłem, ale to działa na 2 bitmapach i maskach, czego ja chciałem uniknąć :(

Może i są tam użyte 4 bitmapy, ale tak naprawdę wystarczy jedna, którą zresztą możesz w locie stworzyć z pliku PNG, być może nawet ten pngimage ma możliwość konwersji do bitmapy.

0

Próbowałem, ale wszystko się zaczęło psuć, cała przezroczystość zrobiła się czarna, w ogóle kiszka :( Może komuś się uda, jak będzie miał chwilke, albo ma jakiś inny pomysł - chętnie wysłucham każdej propozycji bo ja już padam :)

0

Do Image1 władowałem bitmapę 32bit (z Photoshopa, tylko musiała mieć DODATKOWY kanał alpha - nie wystarczyła przeźroczystość warstw). Taki kod działa:

var blend:BLENDFUNCTION;
    P:TPoint;
    S:TSize;
    i,j:integer;
    Linia1,Linia2:PLinia;
begin
SetWindowLong(Form1.Handle, GWL_EXSTYLE, GetWindowLong(Form1.Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
P := Point(0, 0);
S.cx := Image1.Width;
S.cy := Image1.Height;
blend.BlendOp := AC_SRC_OVER;
blend.BlendFlags := 0;
blend.AlphaFormat := AC_SRC_ALPHA;
blend.SourceConstantAlpha := 255;
with TBitmap.Create() do
  begin
  Width:=Image1.Width;
  Height:=Image1.Height;
  PixelFormat:=pf32bit;
  for j:=0 to Height-1 do
    begin
    Linia1:=ScanLine[j];
    Linia2:=Image1.Picture.Bitmap.ScanLine[j];
    for i:=0 to Width-1 do
      begin
      Linia1[i].rgbRed := MulDiv(Linia2[i].rgbRed, Linia2[i].rgbReserved, 255);
      Linia1[i].rgbGreen := MulDiv(Linia2[i].rgbGreen, Linia2[i].rgbReserved, 255);
      Linia1[i].rgbBlue := MulDiv(Linia2[i].rgbBlue, Linia2[i].rgbReserved, 255);
      Linia1[i].rgbReserved := Linia2[i].rgbReserved;
      end;
    end;
  UpdateLayeredWindow(Form1.Handle, GetDC(0), nil, @S, Canvas.Handle, @P, 0, @blend, ULW_ALPHA);
  Free;
  end;
end;
0

[Error] Unit1.pas(31): Undeclared identifier: 'PLinia' :)

0

Sorry

type
TLinia = array[WORD] of TRGBQuad;
PLinia = ^TLinia;
0

Szczawik nie wiem ja Ci dziękować, wszystko działa pięknie [browar]

0

Sorka, że post pod postem ale teraz zobaczyłem, że nie widać moich labeli na tym rysunku :( Czy da się jeszcze poprawić ten kod, żeby je było widać? ;P

0

Bezpośrednio tą metodą nie, gdyż bitmapa definiuje wygląd każdego pikselka - RGB oraz przeźroczystość, ale można pośrednio: najpierw na bitmapie narysować treść: zrobić choćby zrzut z formy, z kolorem tła jako przezroczystym, a potem to ustalić za obraz okna.

0

Myślałem też o 2 formach. Na jednej był by ten obrazek a druga całkowicie przezroczysta przez TransparentColro := True była by na tej z obrazkiem. Wszytko by było ok, gdyby nie to, że ja muszę dać że forma z obrazkiem ma mieć StayOnTop, przez co Labele uciekają mi pod obrazek :/ Może ma ktoś jakiś inny pomysł albo wie jak poprawić ten błąd?

0

A na co Ci koniecznie Label'e? Narysuj to na bitmapie. Zaletą LayeredWindows jest to, że nie trzeba ręcznie odmalowywać treści.

type
  TLinia32 = array[WORD] of TRGBQuad;
  PLinia32 = ^TLinia32;
  TLinia24 = array[WORD] of TRGBTriple;
  PLinia24 = ^TLinia24;
  TLinia8 = array[WORD] of byte;
  PLinia8 = ^TLinia8;

procedure TSplashScreen.FormShow(Sender: TObject);
var blend:BLENDFUNCTION;
    P:TPoint;
    S:TSize;
    i,j:integer;
    bmpRGB, bmpA:TBitmap;
    Linia8:PLinia8;
    Linia24:PLinia24;
    Linia32:PLinia32;
begin
SetWindowLong(SplashScreen.Handle, GWL_EXSTYLE, GetWindowLong(SplashScreen.Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
//Tworzenie warstw RGB oraz A
bmpRGB:=TBitmap.Create();
bmpRGB.Width:=Image1.Width;
bmpRGB.Height:=Image1.Height;
bmpRGB.PixelFormat:=pf24bit;
bmpA:=TBitmap.Create();
bmpA.Width:=Image1.Width;
bmpA.Height:=Image1.Height;
bmpA.PixelFormat:=pf8bit;
//Rozdzielenie Image1.Picture.Bitmap RGBA na RGB oraz A
for j:=0 to Image1.Height-1 do
  begin
  Linia8:=bmpA.ScanLine[j];
  Linia24:=bmpRGB.ScanLine[j];
  Linia32:=Image1.Picture.Bitmap.ScanLine[j];
  for i:=0 to Image1.Width-1 do
    begin
    Linia8[i]:=Linia32[i].rgbReserved;
    Linia24[i].rgbtBlue:=Linia32[i].rgbBlue;
    Linia24[i].rgbtGreen:=Linia32[i].rgbGreen;
    Linia24[i].rgbtRed:=Linia32[i].rgbRed;
    end;
  end;
//Rysowanie po warstwie RGB lub A
bmpRGB.Canvas.Font.Style:=[fsBold];
bmpRGB.Canvas.Brush.Style:=bsClear;
bmpRGB.Canvas.TextOut(10,10,'TEST');
//Sklejenie RGB oraz A
with TBitmap.Create() do
  begin
  Width:=Image1.Width;
  Height:=Image1.Height;
  PixelFormat:=pf32bit;
  for j:=0 to Height-1 do
    begin
    Linia8:=bmpA.ScanLine[j];
    Linia24:=bmpRGB.ScanLine[j];
    Linia32:=ScanLine[j];
    for i:=0 to Width-1 do
      begin
      Linia32[i].rgbRed := MulDiv(Linia24[i].rgbtRed, Linia8[i], 255);
      Linia32[i].rgbGreen := MulDiv(Linia24[i].rgbtGreen, Linia8[i], 255);
      Linia32[i].rgbBlue := MulDiv(Linia24[i].rgbtBlue, Linia8[i], 255);
      Linia32[i].rgbReserved := Linia8[i];
      end;
    end;
  P := Point(0, 0);
  S.cx := Image1.Width;
  S.cy := Image1.Height;
  blend.BlendOp := AC_SRC_OVER;
  blend.BlendFlags := 0;
  blend.AlphaFormat := AC_SRC_ALPHA;
  blend.SourceConstantAlpha := 255;
  UpdateLayeredWindow(SplashScreen.Handle, GetDC(0), nil, @S, Canvas.Handle, @P, 0, @blend, ULW_ALPHA);
  Free;
  end;
bmpA.Free;
bmpRGB.Free;
end;
0

Do Image1 władowałem bitmapę 32bit (z Photoshopa, tylko musiała mieć DODATKOWY kanał alpha - nie wystarczyła przeźroczystość warstw). Taki kod działa:

jestem rowniez zainteresowany tematem
a moje pytanie : jak zapisac w photoshopie dodatkowy kanal alpha aby to dzialalo

bo wlaczylem kanaly zrobilem nowy alpha i mam trzy opcje do wyboru
-obszary zamaskowane
-obszary zaznaczone
-kolor dodatkowy
i krycie koloru w % do ustawienia

i jak nie ustawie to mi to nie dziala
albo wcale nie pokazuje obrazka
albo z tlem

botmapa jest oczywiscie 32bit

0

To nie temat o Photoshopie, ale krótko nie zaszkodzi

Photoshop - od początku:

  • Plik -> Nowy -> RGB -> OK
  • Warstwa -> Nowa.. -> OK
  • Usuwamy warstwę Tło (domyślnie stworzona i nieprzezroczysta)
  • Rysujemy sobie coś z użyciem normalnym przezroczystości na jedynej teraz warstwie
  • Kanały -> Dodaj nowy kanał -> Alpha 1: obszary zamaskowane (kanał jest cały czarny)
  • Zaznaczenie -> Kanał: Przezroczystość warstwy 1
  • Na samym kanale Alpha 1: Edycja ->Wypełnij -> Kolor biały
  • Na warstwie 1 zaznaczamy całą przezroczystość i zamalowujemy na biało (!) [przezroczystość jest teraz tylko na kanale Alpha]
  • Plik -> Zapisz jako.. -> BMP: Windows, 32 bit (A8R8G8B8)
0

kurde Szczawik nie masz pojecia jak ja tego kiedys szukalem ;)
[browar] wielkie dzieki z mojej strony

0

A ja dodam od siebie, że wystarczy utworzyć grafike PNG z cieniami, przezroczystoscia itp, otworzyc go w Paincie i zapisać jako BMP 24-bitową - będzie działało (jak ktoś nie ma Prohoshopa) :P

0
Andre napisał(a)

A ja dodam od siebie, że wystarczy utworzyć grafike PNG z cieniami, przezroczystoscia itp, otworzyc go w Paincie i zapisać jako BMP 24-bitową - będzie działało (jak ktoś nie ma Prohoshopa) :P

:) super efekt
a pomysl z Paintem Andre jeszcze upraszcza sprawe

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