Italia
Fonte/ Codesnippets

Handle sehr grande Bilder Ole

 
- Page 1 -



Jörg
Sellmeyer
Ich hab jetzt via Ole (Dank an Andreas Miethe - immer wieder) ein funktionierendes Handle per Bitmaps (auch gif, ico und diverse andere Formate) ermitteln können, das dann ganz normal auf einem Bitmapstatic angezeigt werden kann. Mit der Ermittlung der Dimensione kann ich mich in dem Fall noch nicht ganz anfreunden. Wer da eine Idee hat - im Code ist die Stelle markiert.

Hier jedenfalls erstmal der Code, um ein gültiges Handle auch per grande Bilder zu erhalten.
Wenn man es im Programm häufiger verwendet, ist es sicher sinnvoller, die Init-Routine nur einmal am Anfang aufzurufen, aber so funktioniert es schon mal klaglos.
Bitte mal mit File größer als 5100 Pixeln testen. Aktuell habe ich es nur mit jpg und gif probiert. Icos sind ja größenmäßig nicht das Problem.
 $H windows.ph
'Konstanten
DEF &Picture_Release     8
DEF &Picture_GetHandle  12
DEF &Picture_GetType    20
DEF &Picture_Get_Width  24
DEF &Picture_Get_Height 28
DEF &Picture_Render     32
DEF &Picture_Select     44
'Globale Variablen
DECLARE IID_IPicture#
DECLARE PData#
DECLARE HMEM&
Declare OlePic#
Class OleImage = OleImage@,\
Ole_Init@,\
Ole_Free@,\
Ole_LoadImage@,\
Ole_GetType@,\
Ole_GetHandle@,\
Ole_FreeImage@,\
OLE32&,\
OLEPro32&,\
PictureObject&,\
hPic&,\
PicFormat&,\
Width&,\
Height&,\
GetSize@,\
Destroy@

Proc OleImage.OleImage

    Parameters File$
    .Ole_Init()
    .PictureObject& = .Ole_LoadImage(File$)
    .PicFormat& = .Ole_GetType(.PictureObject&)
    .hPic& = .Ole_GetHandle()
    Print .PictureObject&,.PicFormat&,.hpic&

EndProc

Proc OleImage.Ole_Init

    .OLE32& = UseDll("OLE32")
    .OLEPRO32& = UseDll("OLEPRO32")
    External("OLE32","OleInitialize",0)
    Dim IID_IPicture#,16
    Long IID_IPicture#,0 = $7BF80980
    Word IID_IPicture#,4 = $BF32
    Word IID_IPicture#,6 = $101A
    Byte IID_IPicture#,8 = $8B
    Byte IID_IPicture#,9 = $BB
    Byte IID_IPicture#,10 = $00
    Byte IID_IPicture#,11 = $AA
    Byte IID_IPicture#,12 = $00
    Byte IID_IPicture#,13 = $30
    Byte IID_IPicture#,14 = $0C
    Byte IID_IPicture#,15 = $AB

EndProc

Proc OleImage.Ole_Free

    ~GlobalFree(Hmem&)
    External("OLE32","OleUninitialize")
    FreeDll .OLE32&
    FreeDll .OLEPRO32&
    DISPOSE IID_IPicture#

EndProc

Proc OleImage.Ole_LoadImage

    Declare MemPointer&,PStream&,PictureObject&,PSize&
    Parameters Picture$
    '------------------------
    Set("Filemode", 0)
    PSIZE& = Filesize(Picture$)
    Dim PData#,PSIZE&
    BlockRead(Picture$,PData#,0,PSIZE&)'Daten in Bereichsvariable einlesen
    '------------------------
    ~GlobalFree(Hmem&)
    HMem& = ~GlobalAlloc($022,PSize&)'Speicher reservieren
    Mempointer& = ~GlobalLock(Hmem&)'Pointer auf Speicher
    ~RtlMoveMemory(MemPointer&,PData#,PSize&)'Bereichsvariable in Speicher schieben
    DISPOSE PData#'Bereichsvariable freigeben
    ~GlobalUnlock(HMem&)'Speicher zum Gebrauch freigeben
    External("Ole32","CreateStreamOnHGlobal",Hmem&,1,addr(PStream&))'Stream-Pointer erstellen
    External("OlePro32","OleLoadPicture",PStream&,PSIZE&,0,IID_IPicture#,ADDR(PictureObject&))'Pointer fuer Pictureobject
    '------------------------
    Case PictureObject& > 0 : Return PictureObject&
    Case PictureObject& = 0 : Return 0

EndProc

Proc OleImage.Ole_GetType

    Declare Command&,PicFormat&
    Command& = Long(.PictureObject&,0)
    Call(@Long(Command&,&Picture_GetType),.PictureObject&,addr(PicFormat&))
    Return PicFormat&

EndProc

Proc OleImage.GetSize

    Parameters DC&
    Declare Command&,w&,h&,xpixels&,ypixels&
    Command& = Long(.PictureObject&,0)
    'hier wird die Bildschirmauflösung pro Zoll abgefragt - bei mir 96x96.
    'Allerdings weiß ich nicht, welche Funktion in welcher dll da angesprochen wird.
    Call(@Long(Command&,&Picture_Get_Width),.PictureObject&,addr(w&))
    Call(@Long(Command&,&Picture_Get_Height),.PictureObject&,addr(h&))
    'die Dimensione des Fensters wird ermittelt
    xpixels& = ~GetDeviceCaps(DC&, 88)
    ypixels& = ~GetDeviceCaps(DC&, 90)
    'Umrechnung der Bildschirmauflösung auf die Fenstergröße.
    'Ich hab allerdings keine Ahnung, wie der Wert 2540 zustande kommt.
    .Width&  = Round((w&*xpixels&)/2540,0)
    .Height& = Round((h&*ypixels&)/2540,0)

EndProc

Proc OleImage.Ole_GetHandle

    Declare Command&,PicHandle&
    Command& = Long(.PictureObject&,0)
    Call(@Long(Command&,&Picture_GetHandle),.PictureObject&,addr(PicHandle&))
    Return PicHandle&

EndProc

Proc OleImage.Ole_FreeImage

    Parameters PictureObject&
    Declare Command&
    Command& = Long(PictureObject&,0)
    Call(@Long(Command&,&Picture_Release),PictureObject&)

EndProc

Proc OleImage.Destroy

    DeleteObject .hPic&,.PictureObject&
    .Ole_Free()

EndProc

Declare hbtn&,Bild$,hFont&,Anzeige&,OleAnzeige&,TestHandle&
UserMessages $10
~SetWindowLong(%hwnd,~GWL_STYLE,(~GetWindowLong(%hwnd,~GWL_STYLE) | $300000))
Window %maxx,%maxy
WindowTitle "Handle per OLE"
hFont& = Create("Font","Western ",14,0,0,0,0)
SetDialogFont hFont&
hbtn& = Create("Button",%hwnd,"Bild laden",%maxx-80,40,60,24)

WhileNot %key = 27'ESC beendet das Programm

    If GetText$(%hwnd) <> "Handle per OLE"

        WaitInput 4000
        WindowTitle "Handle per OLE"
        ShowWindow(hbtn&,5)

    EndIf

    WaitInput
    Case %uMessage = $10:Break

    If Clicked(hbtn&)

        Bild$ = LoadFile$("ÖFFNE","alle unterstützten Formate|*.dib;*.bmp;*.rle;*.jpe;*.jpeg;*.jpg;*.gif;*.ico;*.cur;*.emf;*.wmf|\
        Bitmap (bmp,rle,dib)|*.bmp;*.rle;*.dib|Jpeg (jpg,jpe,jpeg)|*.jpg;*.jpe;*.jpeg|Gif (gif)|*.gif|\
        Enhanced Metafile (emf)|*.emf|Metafile (wmf)|*.wmf|Icons (Ico)|*.ico|Cursor (cur)|*.cur")

        If Bild$ > ""

            TestHandle& = Create("hPic",-1,Bild$)
            'bei grande Bildern ist hier das Ergebnis 0
            WindowTitle Str$(TestHandle&) + " Bei sehr grande Bildern ist das Ergebnis hier 0"
            DeleteObject TestHandle&

            If SizeOf(OlePic#)

                DestroyWindow(OleAnzeige&)
                OlePic#.Destroy()
                Dispose OlePic#

            EndIf

            OlePic# = New(OleImage,Bild$)

            If Anzeige&

                DestroyWindow(Anzeige&)
                waitinput
                Cls

            EndIf

            With OlePic#

                'die Handleermittlung via Ole bringt ein verwertbares Handle:
                OlePic#.GetSize(%hdc2)
                Print .Width&,.Height&,"Typ:",.Ole_GetType()

                If .PicFormat& = 1

                    OleAnzeige& = Create("Bitmap",%hwnd,.hPic&,0,0)
                    .GetSize(%hdc2)
                    Print .Width&,OlePic#.Height&

                ElseIf .PicFormat& = 3

                    Print "Icon ist Typ:",.PicFormat&,"und kann schneller mit Profanmitteln angezeigt werden."

                EndIf

            EndWith

        EndIf

    EndIf

Wend

If SizeOf(OlePic#)

    OlePic#.Destroy()
    Dispose OlePic#

EndIf

DeleteObject hFont&
End

Basierend auf diesem Code  [...]  von Andreas Methe
 
Windows XP SP2 XProfan X4
... und hier mal was ganz anderes als Profan ...
03.06.2020  
 



 
- Page 2 -



RGH
Gerade getestet: Mit Matthias' Code (reines XProfan) konnte ich meine größten Bilder (16 MPixel, Dateigröße circa 6 MB) problemlos laden. Größere Bilder habe ich nicht. Ich benutze meine aktuelle XProfan-Version.

Nachtrag: Und auch das oben verlinkte Afrika-Bild macht in höchster Auflösung (75 MPixel) keine Probleme.

Saluto
Roland
 
Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4
11.06.2020  
 




Matthias
Arlt
Ich hatte mit 11.2 getestet und Jörg vmtl. mit X4. Dann scheinen da wohl noch andere Faktoren eine Rolle zu spielen...nur welche? Mir war das ja auch noch nie aufgefallen, da ich solch grande Bilder eben auch nicht habe.
Ach ja...wenn FreeProfan und OLE sich nicht so recht mögen...meine "schlankere" API-Variante kommt ja ganz ohne OLE aus.
 
WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia
11.06.2020  
 




Jörg
Sellmeyer
RGH (11.06.2020)
Ich habe gerade mal nachgeschaut: Die XProfan-Befehle und -Funktionen, die Bilder aus File laden (MLoadBmp, DrawPic, DrawSizedPic und Create("hPic",...)), nutzen eine OLE-Routine, die an Andreas' Code angelehnt ist. Hier sollte es keine Probleme mit grande Bitmaps geben. Ich muss das mal näher überprüfen.

(Das gilt nicht per FreeProfan, da ich FreePascal noch nicht mit OLE-Objekten verheiraten konnte.)

Saluto
Roland


RGH
Nachtrag: Und auch das oben verlinkte Afrika-Bild macht in höchster Auflösung (75 MPixel) keine Probleme.


Da frage ich mich aber, warum das bei mir nicht funktioniert. Ich hab zwar noch XP mit 2GB Ram aber mit meiner Variante von Andreas' Code funktioniert es ja, also kann es nicht generell am Speicher oder der Windowsversion liegen.
Vielleicht kannst du nochmal schauen, was da die Unterschiede in deiner Version zu meiner sind.
Der verschlankte Code von Matthias funktioniert bei mir übrigens auch nicht.

Außerdem fällt mir auf, dass Matthias print verwendet, um das Bild zu verarbeiten. Das wird in meinem Code vermieden, sondern nur durch Speicherschiebereien das Handle ermittelt.
 
Windows XP SP2 XProfan X4
... und hier mal was ganz anderes als Profan ...
11.06.2020  
 




Matthias
Arlt
@Jörg
Ich habe hier auf diesem PC ja auch XP SP2 drauf. Nachdem nun Roland keine Probleme beim Laden des Bildes hatte, hab ich das Ganze mal schnell in einem virtuellen Win 7 probiert. Und siehe da...dort gibt es auch kein Problem!

Wenn sich nun der profaninterne Code lt. Roland an das OLE-Prozedere von Andreas anlehnt, muß es aber doch Unterschiede geben, denn extern funtioniert es ja mittels OLE.

Das print in meinem Code steht dort eigentlich nur, weil ich das Handle angezeigt bekommen wollte. Warum aber diese API-Variante, die eigentlich nur GDI(+)-Funktionen nutzt, bei Dir nicht geht, ist mir nun wieder ein Rätsel.

Mysteriös...aber immerhin einen Schritt weiter...
 
WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia
11.06.2020  
 




Jörg
Sellmeyer
Ich habs jetzt auch auf nem Laptop mit Win7 und 4GB Ram getestet und es funktioniert mit deinem Code. Das erklärt aber immer noch nicht, warum es bei mir mit meinem Code auch auf mkeinem minderbemittelten Rechner funktioniert aber nicht mit deinem Code.
 
XProfan X4
Windows XP SP2 XProfan X4
... und hier mal was ganz anderes als Profan ...
11.06.2020  
 




Matthias
Arlt
Das ist ja das Mysterium...

GDI+ sollte bei XP ja standardmäßig vorhanden sein. Das ist es also vmtl. nicht.
Du könntest vlt. mal die Rückgabewerte schrittweise per jeden Funktionsaufruf ansehen. Eventuell führt das etwas weiter !?

Festhalten können wir jedenfalls, daß sich create("hPic" unter XP (und wohl nur dort) bei Bildern von annähernd 8000x8000 untypisch verhält. Kein Problem, wenn man das weiß oder solche Bilder nicht hat.

Den folgenden Passus kannst Du auch aus der OLE-Variante entfernen:

TestHandle& = Create("hPic",-1,Bild$)
WindowTitle Str$(TestHandle&) + " Bei sehr grande Bildern ist das Ergebnis hier 0"
DeleteObject TestHandle&

OLE kommt ohne ihn aus und necessario ihn nicht (systemunabhängig). Deshalb ist er dort m.E. auch nicht hilfreich (und stiftet vlt. Verwirrung).
 
WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia
11.06.2020  
 



 
- Page 3 -



Jörg
Sellmeyer
Der Code ist weit davon entfernt, als lauffähiger/nutzbarer Code zu dienen.
Bisher dient er nur zu Test- und Anschauungszwecken.
 
XProfan X4
Windows XP SP2 XProfan X4
... und hier mal was ganz anderes als Profan ...
11.06.2020  
 




Matthias
Arlt
Allein so wie er ist vlt. weniger aber als ausbaufähige Basis schon.
Das was er tun soll "Laden und Anzeigen" klappt doch problemlos.
 
WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia
11.06.2020  
 




RGH
Ich weiß nicht, ob man Energie per Probleme verwenden sollte, die nur beim wirklich veralteten Windows XP auftreten ... zumal ich keine Möglichkeit mehr habe, unter XP zu testen.

Saluto
Roland
 
XProfan X4
Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4
11.06.2020  
 




Matthias
Arlt
@Roland
Nein, ich sehe da auch keinen Handlungsbedarf, nachdem das Problem erkannt und eingegrenzt ist und es funktionierende Workarrounds gibt.

Mit dem veraltet bei XP ist das hin und wieder nicht so einfach. Für bestimmte technische Anwendungen ist XP manchmal schon sowas wie der kleinste gemeinsame Nenner, um unverhältnismäßigen Aufwand zu vermeiden.
 
WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia
11.06.2020  
 




Jörg
Sellmeyer
@Roland; Natürlich kann Io l' Standpunkt verstehen - richtig akzeptieren kann ich die Einstellung nicht.

Es geht hier nicht (nur) um eine veraltete Windowsversion, sondern um ein Programm. was an einer Stelle unnötig Resourcen verbrät. Da kann man sich leicht auf den Standpunkt zurückziehen, soll der Kunde sich doch was Neues/Notizie kaufen, dann corre es auch wieder. Das ist aber eine Einstellung, die mittlerweile dazu geführt hat, dass PC, die früher High-End-Maschinen waren, heutzutage, kaum noch als Bürocomputer taugen, weil selbst die Schreibprogramm so verschwenderisch mit Plattenplatz und Ram umgehen, dass alle zwei Jahre ein neuer PC hermuss, wenn man bei dieser Software Uptodate sein will.
Profan ist zu Glück weit entfernt von solch absurden Auswüchsen, aber es bietet sich an, dem Pfad treu zu bleiben, wenn es doch offensichtlich eine Alternative gibt, die ja anscheinend gar nicht soweit entfernt von den ohnehin eingebauten Codeteilen zu sein scheint.

Grundlage von meinem Code, ist genau der Code  [...]  von Andreas. Ich hab das nur in un Klasse gepackt, weil mir das Format gefällt.
Der einzige Unterschied ist, dass ich das Bild nicht mit den Olemitteln auf den Bildschirm bringe, sondern das Handle nutze, um es weiter mit Profanmitteln zu verarbeiten.
Vielleicht ist das ja schon der Punkt, wo in deinem Code eine kleine Cambiamento Wunder bewirken potuto.
 
XProfan X4
Windows XP SP2 XProfan X4
... und hier mal was ganz anderes als Profan ...
12.06.2020  
 




Matthias
Arlt
Ich hab den "schlanken" Code nochmal überarbeitet. Da waren im Eifer des Probierens 2 Profan-Befehle drin geblieben, die in die API-Routine nicht hineingehören.
 
WinXP SP2, Win7 - XProfan 10/11/FreeProfan32 - Xpia
12.06.2020  
 




Zum Quelltext


Topictitle, max. 100 characters.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Posting  Font  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Topic-Options

9.260 Views

Untitledvor 0 min.
Georg Teles23.05.2024
Sven Bader22.11.2023
Rainer Hoefs01.05.2023
Normann Strübli29.01.2023
Di più...

Themeninformationen



Admins  |  AGB  |  Applications  |  Autori  |  Chat  |  Informativa sulla privacy  |  Download  |  Entrance  |  Aiuto  |  Merchantportal  |  Impronta  |  Mart  |  Interfaces  |  SDK  |  Services  |  Giochi  |  Cerca  |  Support

Ein Projekt aller XProfaner, die es gibt!


Il mio XProfan
Private Notizie
Eigenes Ablageforum
Argomenti-Merkliste
Eigene Beiträge
Eigene Argomenti
Zwischenablage
Annullare
 Deutsch English Français Español Italia
Traduzioni

Informativa sulla privacy


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie