Seite 1 von 1

BITMAP24 in Speicher kopieren

Verfasst: 24.05.2012 15:12
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. ^^

Re: BITMAP24 in Speicher kopieren

Verfasst: 24.05.2012 19:35
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.

Re: BITMAP24 in Speicher kopieren

Verfasst: 24.05.2012 21:22
von Lambda
das *iBuffer 0 ist liegt dann aber doch an TemporaryBitmapInfo\bmiHeader\biSizeImage? .. da vor dem CallFunction, CopyImageToMemory aufgerufen wird

Re: BITMAP24 in Speicher kopieren

Verfasst: 25.05.2012 07:42
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

Re: BITMAP24 in Speicher kopieren

Verfasst: 25.05.2012 19:44
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?

Re: BITMAP24 in Speicher kopieren

Verfasst: 25.05.2012 19:52
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