Bild per API laden und kopieren

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Bild per API laden und kopieren

Beitrag 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?
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Bild per API laden und kopieren

Beitrag 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
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Re: Bild per API laden und kopieren

Beitrag 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...
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Bild per API laden und kopieren

Beitrag 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).
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Re: Bild per API laden und kopieren

Beitrag von jacdelad »

...aber die Funktion ist ein Windows-API-Aufruf. Windows sieht kein #PB_Any vor.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Bild per API laden und kopieren

Beitrag von Mijikai »

Ich dachte LoadImage(#PB_Any,..) war gemeint (Änderung in meinem Beispiel).
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Re: Bild per API laden und kopieren

Beitrag von jacdelad »

Nee, ich meine explizit LoadImage_().

Wie gesagt, mit Bildern geht's jetzt, aber mit Icons noch nicht. GetObject_() scheitert immer beim Icon.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Bild per API laden und kopieren

Beitrag 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).
Zuletzt geändert von Mijikai am 19.04.2021 20:47, insgesamt 1-mal geändert.
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Re: Bild per API laden und kopieren

Beitrag 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.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Bild per API laden und kopieren

Beitrag 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...
Zuletzt geändert von Mijikai am 19.04.2021 20:57, insgesamt 2-mal geändert.
Antworten