BITMAP24 in Speicher kopieren

Für allgemeine Fragen zur Programmierung mit PureBasic.
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

BITMAP24 in Speicher kopieren

Beitrag von Lambda »

Ich bräuchte mal eben Hilfe. :)

Ich erstelle ein Bild(24Bit) und muss es jetzt in einen Buffer schreiben. Mit CopyImageToMemory sollte das schonmal kein Problem sein

Code: Alles auswählen

Procedure CopyImageToMemory(ImageNumber.l, memory.l)
  
  Protected TemporaryDC.l, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO
  
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
  
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
  
  TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
  TemporaryBitmapInfo\bmiHeader\biHeight      = -TemporaryBitmap\bmHeight
  TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
  TemporaryBitmapInfo\bmiHeader\biBitCount    = 24
  TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
  
 ; Speicher reservier ich hier...
  memory= GlobalAlloc_(#GMEM_FIXED|#GMEM_ZEROINIT, TemporaryBitmapInfo\bmiHeader\biSizeImage)
  GetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
  
  DeleteDC_(TemporaryDC)
  
EndProcedure
habe hier biBitCount von 32 auf 24 geändert. Den Buffer schreibe ich in einer Prozedur so

Code: Alles auswählen

Protected *iBuffer.BITMAPINFO

CopyImageToMemory(image, *iBuffer)
Ich schreibe das Bild dann in ein Video

Code: Alles auswählen

CallFunction(ADLL, "AVIStreamWrite", pCompressed, frame, 1,  *iBuffer , *iBuffer\bmiHeader\biSizeImage, #AVIIF_KEYFRAME, 0,0) 
So. Leider stürtzt er genau hier ab. Kann leider nur Ausschnitte liefern da der Code etwas komplexer und groß ist. Hoffe es ist aussagekräftig genug. ^^
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: BITMAP24 in Speicher kopieren

Beitrag von Danilo »

cOoki3druqs hat geschrieben:habe hier biBitCount von 32 auf 24 geändert. Den Buffer schreibe ich in einer Prozedur so

Code: Alles auswählen

Protected *iBuffer.BITMAPINFO

CopyImageToMemory(image, *iBuffer)
Ich schreibe das Bild dann in ein Video

Code: Alles auswählen

CallFunction(ADLL, "AVIStreamWrite", pCompressed, frame, 1,  *iBuffer , *iBuffer\bmiHeader\biSizeImage, #AVIIF_KEYFRAME, 0,0) 
Bei dem CallFunction ist *iBuffer laut den 3 Zeilen Code 0, da es nirgendwo initialisiert wird.
Der Zugriff auf *iBuffer\bmiHeader\biSizeImage crasht somit.

Die Prozedur CopyImageToMemory() sieht aber auch komisch aus, oder sie ist nicht
komplett.

Code: Alles auswählen

 ; Speicher reservier ich hier...
  memory= GlobalAlloc_(#GMEM_FIXED|#GMEM_ZEROINIT, TemporaryBitmapInfo\bmiHeader\biSizeImage)
TemporaryBitmapInfo\bmiHeader\biSizeImage ist laut Deinem Code auch 0.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: BITMAP24 in Speicher kopieren

Beitrag von Lambda »

das *iBuffer 0 ist liegt dann aber doch an TemporaryBitmapInfo\bmiHeader\biSizeImage? .. da vor dem CallFunction, CopyImageToMemory aufgerufen wird
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: BITMAP24 in Speicher kopieren

Beitrag von Danilo »

cOoki3druqs hat geschrieben:das *iBuffer 0 ist liegt dann aber doch an TemporaryBitmapInfo\bmiHeader\biSizeImage? .. da vor dem CallFunction, CopyImageToMemory aufgerufen wird
Nein, Dein CopyImageToMemory setzt *iBuffer nicht.

Probier mal das:

Code: Alles auswählen

Procedure CopyImageToMemory(ImageNumber)
 
  Protected TemporaryDC.i, TemporaryBitmap.BITMAP, TemporaryBitmapInfo.BITMAPINFO, memory.i, size.i
 
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
 
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)
 
  TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
  TemporaryBitmapInfo\bmiHeader\biHeight      = -TemporaryBitmap\bmHeight
  TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
  TemporaryBitmapInfo\bmiHeader\biBitCount    = 24
  TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB
  
  size = TemporaryBitmap\bmWidth * TemporaryBitmap\bmHeight * 3
 
  memory= GlobalAlloc_(#GMEM_FIXED|#GMEM_ZEROINIT, size)
  If memory
    GetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, memory, TemporaryBitmapInfo, #DIB_RGB_COLORS)
  EndIf
  DeleteDC_(TemporaryDC)
 
  ProcedureReturn memory
 
EndProcedure

image = LoadImage(#PB_Any,#PB_Compiler_Home+"Examples\Sources\Data\PureBasic.bmp")
If image
    memory = CopyImageToMemory(image)
    If memory
        ;Debug "OK"
        CallFunction(ADLL, "AVIStreamWrite", pCompressed, frame, 1,  memory , GlobalSize_(memory), #AVIIF_KEYFRAME, 0,0)
        GlobalFree_(memory)
    EndIf
EndIf
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: BITMAP24 in Speicher kopieren

Beitrag von Lambda »

Genialo Danilo, nur seltsamer weiße ist die Datei am Ende leer. ;| Aber der Fehler liegt sicher wo anders.

Edit: ist es eigentlich wirklich korrekt breite*höhe*3 als Buffer zu setzen? Fehlt da nicht der Header?
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: BITMAP24 in Speicher kopieren

Beitrag von Danilo »

cOoki3druqs hat geschrieben:Genialo Danilo, nur seltsamer weiße ist die Datei am Ende leer. ;| Aber der Fehler liegt sicher wo anders.

Edit: ist es eigentlich wirklich korrekt breite*höhe*3 als Buffer zu setzen? Fehlt da nicht der Header?
Das Beispiel setzt nur die reinen Pixeldaten. Was für einen Header brauchst Du denn? BITMAPINFO davor?
Das ist aus dem nicht lauffähigen Schnipsel nicht zu erkennen und in der Hilfe zu AVIStreamWrite_() stand
dazu auch nichts.

Wenn es ein BITMAPINFO Header ist:

Code: Alles auswählen

Procedure CopyImageToMemory(ImageNumber)
 
  Protected TemporaryDC.i, TemporaryBitmap.BITMAP, *TemporaryBitmapInfo.BITMAPINFO, memory.i, size.i
 
  TemporaryDC = CreateDC_("DISPLAY", #Null, #Null, #Null)
 
  GetObject_(ImageID(ImageNumber), SizeOf(BITMAP), TemporaryBitmap.BITMAP)

  size = SizeOf(BITMAPINFO) + TemporaryBitmap\bmWidth * TemporaryBitmap\bmHeight * 3
 
  *TemporaryBitmapInfo= GlobalAlloc_(#GMEM_FIXED|#GMEM_ZEROINIT, size)
  If *TemporaryBitmapInfo
      *TemporaryBitmapInfo\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
      *TemporaryBitmapInfo\bmiHeader\biWidth       = TemporaryBitmap\bmWidth
      *TemporaryBitmapInfo\bmiHeader\biHeight      = -TemporaryBitmap\bmHeight
      *TemporaryBitmapInfo\bmiHeader\biPlanes      = 1
      *TemporaryBitmapInfo\bmiHeader\biBitCount    = 24
      *TemporaryBitmapInfo\bmiHeader\biCompression = #BI_RGB

      GetDIBits_(TemporaryDC, ImageID(ImageNumber), 0, TemporaryBitmap\bmHeight, *TemporaryBitmapInfo+SizeOf(BITMAPINFO), *TemporaryBitmapInfo, #DIB_RGB_COLORS)
  EndIf
  DeleteDC_(TemporaryDC)
 
  ProcedureReturn *TemporaryBitmapInfo
 
EndProcedure

image = LoadImage(#PB_Any,#PB_Compiler_Home+"Examples\Sources\Data\PureBasic.bmp")
If image
    memory = CopyImageToMemory(image)
    If memory
        ;Debug "OK"
        CallFunction(ADLL, "AVIStreamWrite", pCompressed, frame, 1,  memory , GlobalSize_(memory), #AVIIF_KEYFRAME, 0,0)
        GlobalFree_(memory)
    EndIf
EndIf
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Antworten