  | 
					
						Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!   
						
						
					 | 
				 
			 
			 
	
		| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen   | 
	 
	
	
		| Autor | 
		Nachricht | 
	 
	
		UEZ
 
  
  Anmeldungsdatum: 24.06.2016 Beiträge: 147 Wohnort: Opel Stadt
  | 
		
			
				 Verfasst am: 21.07.2016, 16:17    Titel: GDI+ Funktion GdipCreateBitmapFromScan0 | 
				     | 
			 
			
				
  | 
			 
			
				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 | 
		 | 
	 
	
		  | 
	 
	
		Jojo alter Rang
  
  Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
  | 
		
			
				 Verfasst am: 21.07.2016, 18:38    Titel:  | 
				     | 
			 
			
				
  | 
			 
			
				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 | 
		 | 
	 
	
		  | 
	 
	
		UEZ
 
  
  Anmeldungsdatum: 24.06.2016 Beiträge: 147 Wohnort: Opel Stadt
  | 
		
			
				 Verfasst am: 21.07.2016, 19:58    Titel:  | 
				     | 
			 
			
				
  | 
			 
			
				 	  | 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 | 
		 | 
	 
	
		  | 
	 
	
		Jojo alter Rang
  
  Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
  | 
		
			
				 Verfasst am: 21.07.2016, 20:06    Titel:  | 
				     | 
			 
			
				
  | 
			 
			
				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 | 
		 | 
	 
	
		  | 
	 
	
		UEZ
 
  
  Anmeldungsdatum: 24.06.2016 Beiträge: 147 Wohnort: Opel Stadt
  | 
		
			
				 Verfasst am: 21.07.2016, 22:06    Titel:  | 
				     | 
			 
			
				
  | 
			 
			
				 	  | 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 | 
		 | 
	 
	
		  | 
	 
	
		Jojo alter Rang
  
  Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
  | 
		
			
				 Verfasst am: 22.07.2016, 01:24    Titel:  | 
				     | 
			 
			
				
  | 
			 
			
				Manchmal hilft es, die verlinkte Dokumentation zu lesen.  
 
 
 	  | 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 | 
		 | 
	 
	
		  | 
	 
	
		UEZ
 
  
  Anmeldungsdatum: 24.06.2016 Beiträge: 147 Wohnort: Opel Stadt
  | 
		
			
				 Verfasst am: 22.07.2016, 08:40    Titel:  | 
				     | 
			 
			
				
  | 
			 
			
				 	  | Jojo hat Folgendes geschrieben: | 	 		  Manchmal hilft es, die verlinkte Dokumentation zu lesen.  
 
 
 	  | 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.    
 
 
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 | 
		 | 
	 
	
		  | 
	 
	
		Jojo alter Rang
  
  Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
  | 
		
			
				 Verfasst am: 22.07.2016, 12:34    Titel:  | 
				     | 
			 
			
				
  | 
			 
			
				 	  | 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 | 
		 | 
	 
	
		  | 
	 
	
		UEZ
 
  
  Anmeldungsdatum: 24.06.2016 Beiträge: 147 Wohnort: Opel Stadt
  | 
		
			
				 Verfasst am: 22.07.2016, 13:45    Titel:  | 
				     | 
			 
			
				
  | 
			 
			
				 	  | 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 | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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.
  | 
   
 
     |