Tranparentes Fenster und Alphablending
Diese LoadDecodedImage Funktion soll doch dazu sein, um einen Bug im PNG Decoder zu umgehen, weswegen die Alpha Transparenz sonst nicht funktionieren soll. Ich habs aber nun normal mit dem LoadImage Befehl von PB probiert und das PNG wird einwandfrei dargestellt. Kann es sein, dass dieser Code für eine ältere PB Version erstellt wurde und dieser Bug inzwischen gefixt ist? Verwende 4.10 und da funktioniert es wie gesagt auch mit LoadImage.Deluxe0321 hat geschrieben:Code: Alles auswählen
;http://www.purebasic.fr/english/viewtopic.php?p=211814#211814 ;netmaestro [Sat Sep 29, 2007] Procedure StringToBStr (string$) ; By Zapman Inspired by Fr34k Protected Unicode$ = Space(Len(String$)* 2 + 2) Protected bstr_string.l PokeS(@Unicode$, String$, -1, #PB_Unicode) bstr_string = SysAllocString_(@Unicode$) ProcedureReturn bstr_string EndProcedure ProcedureDLL LoadDecodedImage(Filename$) CompilerIf Defined(GdiplusStartupInput, #PB_Structure) = 0 Structure GdiplusStartupInput GdiPlusVersion.l *DebugEventCallback.Debug_Event SuppressBackgroundThread.l SuppressExternalCodecs.l EndStructure CompilerEndIf OpenLibrary(0, "gdiplus.dll") input.GdiplusStartupInput input\GdiPlusVersion = 1 CallFunction(0, "GdiplusStartup", @*token, @input, #Null) CallFunction(0, "GdipCreateBitmapFromFile", StringToBStr(Filename$), @*image) CallFunction(0, "GdipGetImageWidth", *image, @Width.l) CallFunction(0, "GdipGetImageHeight", *image, @Height.l) CallFunction(0, "GdipCreateHBITMAPFromBitmap", *image, @imageid.l, -1) CallFunction(0, "GdipDisposeImage", *image) CallFunction(0, "GdiplusShutdown", *token) CloseLibrary(0) return_imagenumber = CreateImage(#PB_Any, width, height, 32) StartDrawing(ImageOutput(return_imagenumber)) DrawAlphaImage(imageid,0,0) StopDrawing() ProcedureReturn return_imagenumber EndProcedure img = LoadDecodedImage("Documents.png") OpenWindow(0,0,0,300,300,"",#PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible) SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_LAYERED) CreateGadgetList(WindowID(0)) hDC = StartDrawing(ImageOutput(img)) sz.SIZE sz\cx = ImageWidth(img) sz\cy = ImageHeight(img) ContextOffset.POINT BlendMode.BLENDFUNCTION BlendMode\SourceConstantAlpha = 255 BlendMode\AlphaFormat = 1 UpdateLayeredWindow_(WindowID(0), 0, 0, @sz, hDC, @ContextOffset, 0, @BlendMode, 2) StopDrawing() ImageGadget(0,0,0,0,0,ImageID(img)) HideWindow(0,0) Repeat:E=WaitWindowEvent():Delay(5):Until(E=#PB_Event_CloseWindow):End
Das fiel mir nur gerade auf, weil ein zweites PNG Bild unerklärlicher weise zu dunkel dargestellt wurde. Da dachte ich mir ich probiers mal mit LoadImage. Zu meiner Verwunderung war nicht nur die Helligkeit richtig, sondern auch die Transparenz. Kann ich mir diese LoadDecodedImage Funktion ja sparen.
Kann es sein, dass man kein Image mit Alpha Transparenz per ResizeImage im Mode #PB_Image_Smooth verkleinern kann? Krieg da nichts angezeigt, während der RAW Modus funktioniert.
Zuletzt geändert von Hoto am 03.07.2008 12:26, insgesamt 1-mal geändert.
Hi.
Jo, ist mir auch gerade aufgefallen. Das Beispiel was ich habe nutzt auch das normal LoadImage was vollkommen ausreicht.
Wichtig für's transparente Skining ist denke ich nur:
Ein PNG mit Alpha in der Größe zu ändern geht nur mit #PB_Image_Raw , das hattest Du ja auch schon rausbekommen. Ansonsten geht der Alpha Kanal verloren.
Ich hab jetzt schon viel probiert. Also, das Bild via Tastendruck kleiner gemacht und den ganzen Codezweig nochmal ausgeführt. Nur leider ändert sich das Bild dabei nicht. Man merkt zwar beim Verkleinern das sich der Rahmen verändert, aber da wird das Bild nur abgeschnitten. Größe bleibt wie beim Initialisieren erhalten. Komisch?!?
Aber irgendwie muss das doch gehen?
Morty
Jo, ist mir auch gerade aufgefallen. Das Beispiel was ich habe nutzt auch das normal LoadImage was vollkommen ausreicht.
Wichtig für's transparente Skining ist denke ich nur:
Code: Alles auswählen
SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_LAYERED)
hDC = StartDrawing(ImageOutput(img))
sz.SIZE
sz\cx = ImageWidth(img)
sz\cy = ImageHeight(img)
ContextOffset.POINT
BlendMode.BLENDFUNCTION
BlendMode\SourceConstantAlpha = 255
BlendMode\AlphaFormat = 1
UpdateLayeredWindow_(WindowID(0), 0, 0, @sz, hDC, @ContextOffset, 0, @BlendMode, 2)
StopDrawing()
Ich hab jetzt schon viel probiert. Also, das Bild via Tastendruck kleiner gemacht und den ganzen Codezweig nochmal ausgeführt. Nur leider ändert sich das Bild dabei nicht. Man merkt zwar beim Verkleinern das sich der Rahmen verändert, aber da wird das Bild nur abgeschnitten. Größe bleibt wie beim Initialisieren erhalten. Komisch?!?
Aber irgendwie muss das doch gehen?
Morty
Jo, eventuell hab ich aber ne Lösung, wenn ich für folgendes Problem eine Lösung finde. 
Wenn ich mit LoadImage(img,"test.png) ein Image reingeladen habe, wie kann ich das dann an GDI+ übergeben?
GdipDrawImageRectI(*gfx, *image, 0, 0, 160 , 160)
Was muss da statt *image dann rein? Habs schon mit img, ImageID(img) und *img probiert, nix.

Wenn ich mit LoadImage(img,"test.png) ein Image reingeladen habe, wie kann ich das dann an GDI+ übergeben?
GdipDrawImageRectI(*gfx, *image, 0, 0, 160 , 160)
Was muss da statt *image dann rein? Habs schon mit img, ImageID(img) und *img probiert, nix.
Warum?
Das GDI+ Zeugs im oberen Teil des Quellcodes war doch nur ein alter Workaround für das Laden eine PNG mit Alpha. Für das eigentliche Skining braucht man das doch garnicht. Das findet in den von mir erwähnten Zeilen statt.
Aber wenn Du es unbedingt so brauchst, warum lädst Du es dann nicht via GDI+ ? Damit hast Du auf jeden Fall ein gültiges Handle.
Die entsprechenden Funktionen stehen ja auch schon da.
Morty
Das GDI+ Zeugs im oberen Teil des Quellcodes war doch nur ein alter Workaround für das Laden eine PNG mit Alpha. Für das eigentliche Skining braucht man das doch garnicht. Das findet in den von mir erwähnten Zeilen statt.
Aber wenn Du es unbedingt so brauchst, warum lädst Du es dann nicht via GDI+ ? Damit hast Du auf jeden Fall ein gültiges Handle.
Die entsprechenden Funktionen stehen ja auch schon da.
Morty
Weil ich GDI+ vielleicht auch noch für andere Dinge in meinem Programm brauche wofür der normale PB Kram teilweise viel zu langsam ist (z.B. ImageResize)?Morty hat geschrieben:Warum?
Das GDI+ Zeugs im oberen Teil des Quellcodes war doch nur ein alter Workaround für das Laden eine PNG mit Alpha. Für das eigentliche Skining braucht man das doch garnicht. Das findet in den von mir erwähnten Zeilen statt.
Weil damit irgendwas nicht stimmt, eines meiner PNG Bilder kommt viel zu dunkel raus, hat weder was mit gAMA zu tun noch mit dem Bild an sich, alle anderen Programme stellen es richtig dar. Aber vielleicht weiß ja Jemand hierfür eine Lösung, dann bräuchte ich für das andere jetzt auch keine Lösung.Aber wenn Du es unbedingt so brauchst, warum lädst Du es dann nicht via GDI+ ? Damit hast Du auf jeden Fall ein gültiges Handle.
Die entsprechenden Funktionen stehen ja auch schon da.
Code: Alles auswählen
Procedure LoadDecodedImage(Filename$)
GdipCreateBitmapFromFile(Filename$, @*image)
GdipGetImageWidth(*image, @width.l)
GdipGetImageHeight(*image, @height.l)
GdipCreateHBITMAPFromBitmap(*image, @hBitmap.l, 0)
image2.l = CreateImage(#PB_Any,width,height,32)
StartDrawing(ImageOutput(image2))
DrawAlphaImage(hBitmap,0,0)
StopDrawing()
ProcedureReturn image2
EndProcedure

Jemand eine Idee an was das liegen könnte? Bei einem anderen PNG funktioniert das einwandfrei.
Jo, kein Problem.

Im übrigen hab ich inzwischen raus gefunden wie man PB Images an GDI übergeben kann, mit GdipCreateBitmapFromHBITMAP(ImageID(img), 0, @*image). Leider ist dann aber komplett die Transparenz weg, wenn ich das auch noch hinkriegen würde, wäre das Problem auch so beseitigt.
Edit: scheint irgendwas mit der Transparenz zu tun zu haben, beim ursprünglichen Bild ist das FF Symbol nicht durchsichtig, das hab ich erst durchsichtig gemacht und erst dadurch kommt es per GDI+ zu dunkel raus...

Im übrigen hab ich inzwischen raus gefunden wie man PB Images an GDI übergeben kann, mit GdipCreateBitmapFromHBITMAP(ImageID(img), 0, @*image). Leider ist dann aber komplett die Transparenz weg, wenn ich das auch noch hinkriegen würde, wäre das Problem auch so beseitigt.

Edit: scheint irgendwas mit der Transparenz zu tun zu haben, beim ursprünglichen Bild ist das FF Symbol nicht durchsichtig, das hab ich erst durchsichtig gemacht und erst dadurch kommt es per GDI+ zu dunkel raus...
Leider nein. Kann mir vielleicht jemand sagen, wie ich an das Image komme, wenn ich es per IncludeBinary einbinde? CatchImage() is schon klar, aber wo muss ich das Handle an das GDI-Gedöns (dass ich btw gar nich raff) übergeben?Hoto hat geschrieben:Niemand sonst ne Idee wieso GDI+ hier Murks macht?