Hi Programie,
die beiden Prozeduren CopyImageToMem() und CopyMemToImage() scheinen genau dein Anliegen zu erfüllen. Die dritte Prozedur Filtern() dient lediglich dazu einen Weichzeichnen-Effekt zu realisieren, wonach der Thread-Ersteller gefragt hatte.
Ich habe mal einen Code zusammengebastelt, der ein Bild erstellt, in einen Speicherbereich schreibt, es zusammen mit anderen Daten in eine Datei schreibt, dann wieder lädt und anzeigt.
Code: Alles auswählen
Procedure CopyImageToMem(Img.l, mem.l)
Protected bmi.BITMAPINFO
Protected w.l, h.l, hBmp.l, hDC.l
w = ImageWidth(Img)
h = ImageHeight(Img)
hBmp = ImageID(Img)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = w
bmi\bmiHeader\biHeight = -h
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
hDC = StartDrawing( ImageOutput(Img) )
If GetDIBits_(hDC, hBmp, 0, h, mem, bmi, #DIB_RGB_COLORS)
StopDrawing()
ProcedureReturn #True
Else
StopDrawing()
ProcedureReturn #False
EndIf
EndProcedure
Procedure CopyMemToImage(mem.l, Img.l)
Protected bmi.BITMAPINFO
Protected w.l, h.l, hBmp.l, hDC.l
w = ImageWidth(Img)
h = ImageHeight(Img)
hBmp = ImageID(Img)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = w
bmi\bmiHeader\biHeight = -h
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
hDC = StartDrawing( ImageOutput(Img) )
If SetDIBits_(hDC, hBmp, 0, h, mem, bmi, #DIB_RGB_COLORS)
StopDrawing()
ProcedureReturn #True
Else
StopDrawing()
ProcedureReturn #False
EndIf
EndProcedure
;- Image erstellen
CreateImage(0, 8, 8, 32)
StartDrawing(ImageOutput(0))
Box(0, 0, 8, 8, $FFFF00)
Plot(0, 0, $FF0000)
Plot(7, 7, $0000FF)
StopDrawing()
;- Image anzeigen
OpenWindow(0, #PB_Ignore, #PB_Ignore, 200, 200, "Image (1) - direkt nach Erstellung", #PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ImageGadget(0, 0, 0, 200, 200, ImageID(0))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
CloseWindow(0)
;- Image in Speicher kopieren
*mem = AllocateMemory(ImageWidth(0)*ImageHeight(0)*4)
If CopyImageToMem(0, *mem) = 0
MessageRequester("Fehler", "Image -> Mem fehlgeschlagen")
End
EndIf
;- zur Kontrolle ob das geklappt hat, Farbwerte der einzelnen Pixel ausgeben
For i=0 To 8*8 - 1
Debug PeekL(*mem + i*4)
Next
Debug "-----"
;- Image zusammen mit anderen Daten in Datei schreiben
CreateFile(0, "img.dat")
WriteLong(0, MemorySize(*mem)) ; Größe des Speichers
WriteLong(0, ImageWidth(0)) ; Breite
WriteLong(0, ImageHeight(0)) ; Höhe
WriteLong(0, 32) ; Farbtiefe
WriteData(0, *mem, MemorySize(*mem)) ; Pixel des Bilds
WriteString(0, "übrige Informationen...")
CloseFile(0)
;- Image und Speicher freigeben (um zu zeigen, dass es tatsächlich wieder geladen wird)
FreeImage(0)
FreeMemory(*mem)
;- Datei öffnen und Bild laden
ReadFile(0, "img.dat")
*mem = AllocateMemory(ReadLong(0)) ; Speicher erstellen
width = ReadLong(0)
height = ReadLong(0)
depth = ReadLong(0)
CreateImage(0, width, height, depth) ; Image erstellen
ReadData(0, *mem, MemorySize(*mem)) ; Daten in Speicher kopieren
Debug ReadString(0) ; übrige Daten auslesen ...
CopyMemToImage(*mem, 0) ; Daten aus Speicher wieder auf Image kopieren
;- Image noch einmal anzeigen
OpenWindow(0, #PB_Ignore, #PB_Ignore, 200, 200, "Image (2) - nach dem Laden aus der Datei", #PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ImageGadget(0, 0, 0, 200, 200, ImageID(0))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
CloseWindow(0)
Ebenfalls interessant: Aufbau von Bitmaps allgemein:
http://www.fortunecity.com/skyscraper/w ... ffrmt.html
Edit: Habe gerade die Geschwindigkeit von SaveImage() und dem Weg über Memory verglichen.
Zumindest beim Speichern ist die Memory-Variante ein bisschen schneller (42807ms statt 48673).