Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

GDI+ Funktion GdipCreateBitmapFromScan0

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
UEZ



Anmeldungsdatum: 24.06.2016
Beiträge: 76
Wohnort: Opel Stadt

BeitragVerfasst am: 21.07.2016, 16:17    Titel: GDI+ Funktion GdipCreateBitmapFromScan0 Antworten mit Zitat

Wie kann ich unter FB den Scan0 Parameter in der GDI+ Funktion GdipCreateBitmapFromScan0 implementieren, um direkt in die Bitmap zu zeichnen? Ich möchte nicht die Funktion GdipBitmapLockBits benutzen!

Dokumentation zu dieser Funktion: "https://msdn.microsoft.com/en-us/library/windows/desktop/ms536315(v=vs.85).aspx"

Was ich bisher versucht habe:
Code:
#Include Once "win\gdiplus.bi"

Using GDIPLUS


Declare Function Test(ByVal hImage As Any Ptr = 0) As Any Ptr



Type tBitmapData
   scan0(0 To 512 * 4) As UByte
End Type

Function Test(ByVal hImage As Any Ptr = 0) As Any Ptr
   Dim As Single iW, iH
   Dim As Any Ptr hBitmap
   Dim bmp AS BITMAPDATA
   Dim As Integer iStatus
   
   Dim As UByte Ptr pARGB
   Dim pBitmapData As tBitmapData

   
   GdipCreateBitmapFromScan0(512, 512, 512 * 4, PixelFormat32bppARGB, @pBitmapData, @hBitmap)
   'GdipCreateBitmapFromScan0(512, 512, 512 * 4, PixelFormat32bppARGB, 0, @hBitmap)
   
   
   Return hBitmap
End Function


Dim GDIPlusStartupInput As GDIPLUSSTARTUPINPUT
Dim As ULONG_PTR GDIPlusToken

GDIPlusStartupInput.GdiplusVersion = 1
If (GdiplusStartup(@GDIPlusToken, @GDIPlusStartupInput, NULL) <> 0) Then
    Print "FAILED TO INIT GDI+!"
EndIf

Dim hBmp_new As Any Ptr

hBmp_new = Test()
Print "Handle: ";hBmp_new


Dim CLSID_01 As CLSID
CLSIDFROMSTRING(WStr("{557CF406-1A04-11D3-9A73-0000F81EF32E}"), @CLSID_01)

If (GdipSaveImageToFile(hBmp_new, WStr("1.png"), @CLSID_01 , NULL) <> 0) Then
   Print "Image save has FAILED!"
EndIf

   
GdipDisposeImage(hBmp_new)

GdiplusShutdown(GDIPlusToken)

Sleep


Danke.
_________________
Gruß,
UEZ
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 21.07.2016, 18:38    Titel: Antworten mit Zitat

Du brauchst den Pointer auf den Inhalt des Arrays, also vmtl @pBitmapData .scan0(0) und nicht @pBitmapData .
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
UEZ



Anmeldungsdatum: 24.06.2016
Beiträge: 76
Wohnort: Opel Stadt

BeitragVerfasst am: 21.07.2016, 19:58    Titel: Antworten mit Zitat

Jojo hat Folgendes geschrieben:
Du brauchst den Pointer auf den Inhalt des Arrays, also vmtl @pBitmapData .scan0(0) und nicht @pBitmapData .


Wenn ich den Code mit
Code:
GdipCreateBitmapFromScan0(512, 512, 512 * 4, PixelFormat32bppARGB, @pBitmapData.scan0(0), @hBitmap)

ausführe, dann stürzt die Exe ab (wahrscheinlich mit einer Speicherschutzverletzung).
_________________
Gruß,
UEZ
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 21.07.2016, 20:06    Titel: Antworten mit Zitat

Dein Array ist ja auch viel zu klein. Da passt eine Zeile rein, und du gibst an, dass das Bild 512 Zeilen hat.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
UEZ



Anmeldungsdatum: 24.06.2016
Beiträge: 76
Wohnort: Opel Stadt

BeitragVerfasst am: 21.07.2016, 22:06    Titel: Antworten mit Zitat

Jojo hat Folgendes geschrieben:
Dein Array ist ja auch viel zu klein. Da passt eine Zeile rein, und du gibst an, dass das Bild 512 Zeilen hat.


Stimmt. 32Bit hat 4 Bytes pro Pixel. Somit sollte 512 * 512 * 4 das Array groß sein.

Code:
#Include Once "win\gdiplus.bi"

Using GDIPLUS


Declare Function Test(ByVal hImage As Any Ptr = 0) As Any Ptr

Type tBitmapData
   scan0(0 To 512 * 512 * 4) As UByte
End Type


Function Test(ByVal hImage As Any Ptr = 0) As Any Ptr
   Dim As Single iW, iH
   Dim As Any Ptr hBitmap
   Dim bmp AS BITMAPDATA
   Dim As Integer iStatus
   
   Dim As UByte Ptr pARGB
   Dim pBitmapData As tBitmapData
   
   GdipCreateBitmapFromScan0(512, 512, 512 * 4, PixelFormat32bppARGB, @pBitmapData.scan0(0), @hBitmap)
   
   Return hBitmap
End Function


Dim GDIPlusStartupInput As GDIPLUSSTARTUPINPUT
Dim As ULONG_PTR GDIPlusToken

GDIPlusStartupInput.GdiplusVersion = 1
If (GdiplusStartup(@GDIPlusToken, @GDIPlusStartupInput, NULL) <> 0) Then
    Print "FAILED TO INIT GDI+!"
EndIf

Dim hBmp_new As Any Ptr

hBmp_new = Test()
Print "Handle: ";hBmp_new


Dim CLSID_01 As CLSID
CLSIDFROMSTRING(WStr("{557CF406-1A04-11D3-9A73-0000F81EF32E}"), @CLSID_01)

If (GdipSaveImageToFile(hBmp_new, WStr("1.png"), @CLSID_01 , NULL) <> 0) Then
   Print "Image save has FAILED!"
EndIf

   
GdipDisposeImage(hBmp_new)

GdiplusShutdown(GDIPlusToken)

Sleep


Hmmm, funktioniert trotzdem nicht.
_________________
Gruß,
UEZ
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 22.07.2016, 01:24    Titel: Antworten mit Zitat

Manchmal hilft es, die verlinkte Dokumentation zu lesen. zwinkern

Zitat:
Pointer to an array of bytes that contains the pixel data. The caller is responsible for allocating and freeing the block of memory pointed to by this parameter.

Das von dir erstellte Array verliert nach verlassen der Test-Funktion seine Gültigkeit. Es muss aber mindestens bis zum GdipDisposeImage verfügbar sein, sonst schreibt oder liest GDI+ Speicher, der schon freigegeben wurde!

Code:
#Include Once "win\gdiplus.bi"

Using GDIPLUS


Declare Function Test(ByVal hImage As Any Ptr = 0) As Any Ptr

Dim Shared As Byte bitmap(0 To (512 * 512 * 4) - 1)

Function Test(ByVal hImage As Any Ptr = 0) As Any Ptr
   Dim As Single iW, iH
   Dim As Any Ptr hBitmap
   Dim bmp AS BITMAPDATA
   Dim As Integer iStatus
   
   GdipCreateBitmapFromScan0(512, 512, 512 * 4, PixelFormat32bppARGB, @bitmap(0), @hBitmap)
   
   Return hBitmap
End Function


Dim GDIPlusStartupInput As GDIPLUSSTARTUPINPUT
Dim As ULONG_PTR GDIPlusToken

GDIPlusStartupInput.GdiplusVersion = 1
If (GdiplusStartup(@GDIPlusToken, @GDIPlusStartupInput, NULL) <> 0) Then
    Print "FAILED TO INIT GDI+!"
EndIf

Dim hBmp_new As Any Ptr

hBmp_new = Test()
Print "Handle: ";hBmp_new

For i As Integer = 0 To UBound(bitmap)
   bitmap(i) = i
Next

Dim CLSID_01 As CLSID
CLSIDFROMSTRING(WStr("{557CF406-1A04-11D3-9A73-0000F81EF32E}"), @CLSID_01)

If (GdipSaveImageToFile(hBmp_new, WStr("C:\1.png"), @CLSID_01 , NULL) <> 0) Then
   Print "Image save has FAILED!"
EndIf

   
GdipDisposeImage(hBmp_new)

GdiplusShutdown(GDIPlusToken)

Sleep

_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
UEZ



Anmeldungsdatum: 24.06.2016
Beiträge: 76
Wohnort: Opel Stadt

BeitragVerfasst am: 22.07.2016, 08:40    Titel: Antworten mit Zitat

Jojo hat Folgendes geschrieben:
Manchmal hilft es, die verlinkte Dokumentation zu lesen. zwinkern

Zitat:
Pointer to an array of bytes that contains the pixel data. The caller is responsible for allocating and freeing the block of memory pointed to by this parameter.

Das von dir erstellte Array verliert nach verlassen der Test-Funktion seine Gültigkeit. Es muss aber mindestens bis zum GdipDisposeImage verfügbar sein, sonst schreibt oder liest GDI+ Speicher, der schon freigegeben wurde!


Danke Jojo. lächeln

Nun ja, ich dachte, dass ich mit
Code:
Type tBitmapData
   scan0(1 To 512 * 512 * 4) As Byte
End Type

den Speicherblock zugeteilt habe, zumal ich in der Funktion die Pixel setzen möchte.
Ok, über die FB Internas gibt es noch viel zu lernen, was wann zugreifbar ist und wann nicht.

Btw, wie kann ich
Code:
Dim Shared As Byte bitmap(0 To (512 * 512 * 4) - 1)

dynamisch halten, wenn ich z.B. dieses Array anhand eines geladenen Bildes erstellen möchte?
_________________
Gruß,
UEZ
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 22.07.2016, 12:34    Titel: Antworten mit Zitat

Zitat:
den Speicherblock zugeteilt habe, zumal ich in der Funktion die Pixel setzen möchte.

Nein, ein TYPE ist quasi nur eine Vorlage für ein später zu erstellendes Objekt. Du musst entweder ein Array im globalen Scope erstellen (so wie ich das hier im Beispiel gemacht habe, was aber ziemlich unsauber ist) oder das Array mit NEW dynamisch erstellen und mit DELETE nach Verwendung wieder löschen.

Zitat:
Dim Shared As Byte bitmap(0 To (512 * 512 * 4) - 1)

Die Frage verstehe ich nicht ganz - du möchtest ein Bild von der Platte in ein vordefiniertes Array packen? Wenn ja, musst du schauen welche GDI+-Funktionen sich dafür anbieten. Höchstwahrscheinlich wird es aus Sicherheitsgründen keine Funktion geben, die beliebige Bilder von der Platte in ein Array lesen kann (da du ja im Allgemeinen vorher nicht weißt, wie groß das Array sein muss), aber du kannst sicher das Bild normal laden und dann in dein Array rüberkopieren.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
UEZ



Anmeldungsdatum: 24.06.2016
Beiträge: 76
Wohnort: Opel Stadt

BeitragVerfasst am: 22.07.2016, 13:45    Titel: Antworten mit Zitat

Zitat:
Die Frage verstehe ich nicht ganz - du möchtest ein Bild von der Platte in ein vordefiniertes Array packen? Wenn ja, musst du schauen welche GDI+-Funktionen sich dafür anbieten. Höchstwahrscheinlich wird es aus Sicherheitsgründen keine Funktion geben, die beliebige Bilder von der Platte in ein Array lesen kann (da du ja im Allgemeinen vorher nicht weißt, wie groß das Array sein muss), aber du kannst sicher das Bild normal laden und dann in dein Array rüberkopieren.

Ich hatte bereits ein Thema zu GDI+ und Multithreading aufgemacht, nur ist diese Lösung keine performante Lösung, da sie, je höher der Threadanteil, langsamer läuft.

Was ich im Prinzip machen will ist ein Bild laden und dieses Bild per Multi Threading manipulieren (z.B. Median Filter). Die DLL mit den diversen Filtern habe ich bereits fertig gestellt, wollte aber die "langsamen" Funktionen per Multi Threading beschleunigen.
Da das Array von dem Quell Bild abhängt, muss es dynamisch erstellt werden. Die 512x512 Pixel waren nur Test, um zu verstehen, wie ich das implementieren kann.
_________________
Gruß,
UEZ
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz