Seite 1 von 2

Bild per API laden und kopieren

Verfasst: 19.04.2021 16:14
von jacdelad
Hallo,
ich will ein Bild per Windows API laden und dann weiterverarbeiten. Hintergrund ist mein RibbonGadget, das auch als DLL für XProfan bereit stehen soll. Das Bild wird in dem Fall vom XProfan-Programm geladen und an die DLL übergeben. Das hat auch erst funktioniert, jetzt habe ich aber eine ganze Menge geändert und plötzlich klappt es nicht mehr. ich habe meine Backups durchgesehen und konnte an den Stellen, die ich für entscheidend halte, keine Unterschiede feststellen.

Lange Rede, kurzer Sinn: Das Problem ist, dass GetObject_() immer 0 zurückgibt, also fehlschlägt. Deshalb kann das (für die DLL externe) Bild nicht weiterverwendet werden. In der DLL sollen Eigenschaften wie Breite und Höhe per GetObject_() ausgelesen werden (wie gesagt, das schlägt fehl). Mein Ablauf ist in etwa Bild -> GetObject_() -> StartDrawing() auf Zielbild -> DrawImage() auf Zielbild (ImageID vom Quellbild entfällt, weil es ja ein Handle und keine ID ist).

Jetzt habe ich ein minimales Beispiel geschrieben. Mit Bitmaps funktioniert GetObject, mit Icons aber nicht:

Code: Alles auswählen

image=LoadImage_(GetModuleHandle_(0),"D:\PureBasic\Ribbon\Icon1.ico",#IMAGE_ICON,1080,1080,#LR_LOADFROMFILE)
Debug image
Debug GetObject_(image,SizeOf(bitmap),@bm.bitmap)
Bin ich hier überhaupt auf dem richtigen Weg? Wie gesagt, die DLL ging erst, jetzt aber plötzlich nicht mehr.
Nochmal zusammengefasst: Das aufrufende Programm übergibt das Handle eines Bildes (erzeugt mit LoadImage_()) an die DLL. Die soll das Bild in ein neues Bild, das mit PureBasic-Befehlen erstellt wurde, kopiert werden.

Kann mir da jemand helfen?

Re: Bild per API laden und kopieren

Verfasst: 19.04.2021 17:57
von Mijikai
Ich nutze GetObject_() oft für die Bildmanipulation da es viel einfacher ist als jedesmal Start & StopDrawing aufzurufen
um and die Bits und andere Informationen zu kommen.
jacdelad hat geschrieben: 19.04.2021 16:14

Code: Alles auswählen

image=LoadImage_(GetModuleHandle_(0),"D:\PureBasic\Ribbon\Icon1.ico",#IMAGE_ICON,1080,1080,#LR_LOADFROMFILE)
Debug image
Debug GetObject_(image,SizeOf(bitmap),@bm.bitmap)
Der Beispielcode könnte so problematisch sein da GetModuleHandle_() zu hohe Werte ausgeben kann,
zudem ist es nicht klar ob der Returncode hier immer das Icon Handle ist.
Besser #PB_Any verwenden (oder eine definierte Nummer).

Mit Icons kenne ich mich nicht gut aus aber ich glaube das Icons nur Container sind die mehreren Einzelbildern enthalten können.
Evtl. reicht GetIconInfo_(), müsste mal bei MSDN schauen ob es da mehr Infos oder Limitationen gibt.

Beispiel mit GetIconInfo_()

Code: Alles auswählen

EnableExplicit

Procedure.i Main()
  Protected img.i
  Protected ico.ICONINFO
  Protected bm.BITMAP
  img = LoadImage(#PB_Any,"OneDrive.ico");<- icon einer nutzlosen windows spyware app als beispiel
  If IsImage(img)
    If GetIconInfo_(ImageID(img),@ico);<- container 'öffnen'
      If GetObject_(ico\hbmColor,SizeOf(BITMAP),@bm);<- bitmap info mit handle holen
        Debug bm\bmWidth
        Debug bm\bmHeight
      EndIf
    EndIf
    FreeImage(img)
  EndIf
  ProcedureReturn
EndProcedure

Main()

End

Re: Bild per API laden und kopieren

Verfasst: 19.04.2021 18:29
von jacdelad
#PB_Any kann ich nicht nehmen, weil es keine PureBasic-eigene Funktion ist.

Das Icon war auch nur ein Beispiel. In XProfan nutze ich die eingebauten Funktionen. Ich gab gerade gesehen, dass das Problem wohl doch an XProfan liegt. Bilder gehen, Icons nicht...

Re: Bild per API laden und kopieren

Verfasst: 19.04.2021 19:02
von Mijikai
jacdelad hat geschrieben: 19.04.2021 18:29 #PB_Any kann ich nicht nehmen, weil es keine PureBasic-eigene Funktion ist.
...
? #PB_Any ist nur ein Parameter, intern wird immer die jeweilige OS Api (Lib/System) verwendet.
Die Nummer Variante ist nur eine unnötige zusätzliche Verschachtelung aus Kompatibilitätsgründen (Syntax Historie).

Re: Bild per API laden und kopieren

Verfasst: 19.04.2021 19:04
von jacdelad
...aber die Funktion ist ein Windows-API-Aufruf. Windows sieht kein #PB_Any vor.

Re: Bild per API laden und kopieren

Verfasst: 19.04.2021 19:10
von Mijikai
Ich dachte LoadImage(#PB_Any,..) war gemeint (Änderung in meinem Beispiel).

Re: Bild per API laden und kopieren

Verfasst: 19.04.2021 19:16
von jacdelad
Nee, ich meine explizit LoadImage_().

Wie gesagt, mit Bildern geht's jetzt, aber mit Icons noch nicht. GetObject_() scheitert immer beim Icon.

Re: Bild per API laden und kopieren

Verfasst: 19.04.2021 20:32
von Mijikai
jacdelad hat geschrieben: 19.04.2021 19:04 ...aber die Funktion ist ein Windows-API-Aufruf. Windows sieht kein #PB_Any vor.
jacdelad hat geschrieben: 19.04.2021 19:16 Nee, ich meine explizit LoadImage_().

Wie gesagt, mit Bildern geht's jetzt, aber mit Icons noch nicht. GetObject_() scheitert immer beim Icon.
:?
LoadImage() ist aber keine Windows API sonder die PB Wrapper Funktion für die OS Api... #PB_Any ist irrelevant zum Problem.
GetModuleHandle_() kann aber ein zusätzliches Problem werden wie schon beschrieben.

Geht mein Beispiel nicht oder liegt as an XProfan... ???

Hier nochmal der GetIconInfo_() Versuch als Funktion (Image.i = #Image )

Code: Alles auswählen

Procedure.i GeWindowsImageHandle(Image.i)
  Protected ico.ICONINFO
  If IsImage(Image)
    If GetIconInfo_(ImageID(Image),@ico)
      ProcedureReturn ico\hbmColor
    Else
      ProcedureReturn ImageID(Image)
    EndIf
  EndIf
  ProcedureReturn #Null
EndProcedure


GetIconInfo_() ist die Funktion die ich kenne aber am besten nochmal bei MSDN
nachlesen ob das für den Anwendungsfall ausreichend ist (Stichwort Multi-Image Icons).

Re: Bild per API laden und kopieren

Verfasst: 19.04.2021 20:46
von jacdelad
Junge!

Das Bild stammt vom aufrufenden Programm. Das ist nicht in PureBasic geschrieben, also kann es auch keine PureBasic-Funktionen nutzen. Deshalb die DLL. Es nutzt LoadImage_(), also um ehrlich zu sein nutzt es ~LoadImage(...), das Pendant von PureBasic ist LoadImage_(). Mit Unterstrich. Weil API-Aufruf. Und nein, ich kann nicht die interne Funktion nutzen. Weil das aufrufende Programm nicht in PureBasic geschrieben ist.

Re: Bild per API laden und kopieren

Verfasst: 19.04.2021 20:49
von Mijikai
jacdelad hat geschrieben: 19.04.2021 20:46 Junge!

Das Bild stammt vom aufrufenden Programm. Das ist nicht in PureBasic geschrieben, also kann es auch keine PureBasic-Funktionen nutzen. Deshalb die DLL. Es nutzt LoadImage_(), also um ehrlich zu sein nutzt es ~LoadImage(...), das Pendant von PureBasic ist LoadImage_(). Mit Unterstrich. Weil API-Aufruf. Und nein, ich kann nicht die interne Funktion nutzen. Weil das aufrufende Programm nicht in PureBasic geschrieben ist.
/:->
...GetIconInfo_() is eine OS API Funktion ImageID ist hIcon...

Code: Alles auswählen

Procedure.i GetBitmap(Handle.i,*Bitmap);<- in DLL
  Protected ico.ICONINFO
  If GetIconInfo_(Handle,@ico)
    Handle = ico\hbmColor
  EndIf
  ProcedureReturn GetObject_(Handle,SizeOf(BITMAP),*Bitmap)
EndProcedure
Ich gebs auf...