Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
cxAlex
Beiträge: 2111 Registriert: 26.06.2008 10:42
Beitrag
von cxAlex » 14.04.2009 20:13
Nachdem ich eine Featurerequest im englishen Forum gemacht hab, Bilder direkt in den Speicher zu sichern, hat mir srod einen Tip gegeben, den ich nun zu einer Procedure verwurstet hab:
http://www.purebasic.fr/english/viewtop ... 247#283247
Code: Alles auswählen
Procedure SaveImageToMemory(Image, *MemSize, Format = #PB_ImagePlugin_BMP, Compression = 7)
Protected *Mem, MemSize, ImageDataPipe
MemSize = ImageDepth(Image)*ImageHeight(Image)*ImageWidth(Image)
*Mem = AllocateMemory(MemSize)
ImageDataPipe = CreateNamedPipe_("\\.\pipe\ImageDataPipe", #PIPE_ACCESS_INBOUND | #FILE_FLAG_OVERLAPPED, #PIPE_TYPE_BYTE | #PIPE_READMODE_BYTE | #PIPE_NOWAIT, 1, MemSize, MemSize, #NMPWAIT_USE_DEFAULT_WAIT, #Null)
SaveImage(Image, "\\.\pipe\ImageDataPipe", Format, Compression)
ReadFile_(ImageDataPipe, *Mem, MemSize, *MemSize, #Null)
CloseHandle_(ImageDataPipe)
ProcedureReturn *Mem
EndProcedure
Ich brauch sowas immer wieder, ganz nützlich.
Zuletzt geändert von
cxAlex am 15.04.2009 16:42, insgesamt 1-mal geändert.
KeyKon
Beiträge: 1412 Registriert: 10.09.2004 20:51
Computerausstattung: Laptop: i5 2,8 Ghz, 16GB DDR3 RAM, GeForce 555GT 2GB VRAM PC: i7 4,3 Ghz, 32GB DDR3 RAM, GeForce 680 GTX 4GB VRAM Win10 x64 Home/Prof PB 5.30 (64bit)
Wohnort: Ansbach
Kontaktdaten:
Beitrag
von KeyKon » 15.04.2009 00:32
Klasse
Lass mich raten, das ganze läuft auch in deinem DesktopStreamer^^
(\/) (°,,,°) (\/)
cxAlex
Beiträge: 2111 Registriert: 26.06.2008 10:42
Beitrag
von cxAlex » 15.04.2009 06:35
KeyKon hat geschrieben: Klasse
Lass mich raten, das ganze läuft auch in deinem DesktopStreamer^^
exakt, in der nächsten Version ists drin ^^
KeyKon
Beiträge: 1412 Registriert: 10.09.2004 20:51
Computerausstattung: Laptop: i5 2,8 Ghz, 16GB DDR3 RAM, GeForce 555GT 2GB VRAM PC: i7 4,3 Ghz, 32GB DDR3 RAM, GeForce 680 GTX 4GB VRAM Win10 x64 Home/Prof PB 5.30 (64bit)
Wohnort: Ansbach
Kontaktdaten:
Beitrag
von KeyKon » 15.04.2009 11:34
Btw, ich bin zwar kein Englisch-Guru, aber ich meine der Topic müsste Sa
v eImageToMemory() heißen
(\/) (°,,,°) (\/)
DarkDragon
Beiträge: 6291 Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:
Beitrag
von DarkDragon » 15.04.2009 11:47
Hmm... das müsste so ähnlich sicher auch unter Linux gehen.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Andesdaf
Moderator
Beiträge: 2671 Registriert: 15.06.2008 18:22
Wohnort: Dresden
Beitrag
von Andesdaf » 15.04.2009 16:29
KeyKon hat geschrieben: Btw, ich bin zwar kein Englisch-Guru, aber ich meine der Topic müsste Sa
v eImageToMemory() heißen
Nur der Threadtitel ist falsch (meiner Meinung nach), die Procedure an sich ist richtig.
Win11 x64 | PB 6.20
cxAlex
Beiträge: 2111 Registriert: 26.06.2008 10:42
Beitrag
von cxAlex » 15.04.2009 16:43
Jo mein Fehler
.
Beim Programmieren kam mir PB mit der Autovervollständigung entgegen, im Titel hat sich mein schlechtes Englisch durchgesetzt
.
Andesdaf
Moderator
Beiträge: 2671 Registriert: 15.06.2008 18:22
Wohnort: Dresden
Beitrag
von Andesdaf » 15.04.2009 18:11
allgemein zur Procedure
cxAlex
Beiträge: 2111 Registriert: 26.06.2008 10:42
Beitrag
von cxAlex » 25.04.2009 00:17
Update:
Das ganze ist nun Thread-Safe, bei massiver verwendung in Threads konnte es zu Kollisionen mit der Pipe kommen:
Code: Alles auswählen
Procedure SaveImageToMemory(Image, *MemSize, Format = #PB_ImagePlugin_JPEG, Compression = 9)
Protected *Mem, MemSize, ImageDataPipe, PipeName$
PipeName$ = "\\.\pipe\ImageDataPipe_" + Str(GetCurrentThreadId_()) ; <- Threadsicher
MemSize = ImageDepth(Image)*ImageHeight(Image)*ImageWidth(Image)
*Mem = AllocateMemory(MemSize)
ImageDataPipe = CreateNamedPipe_(PipeName$, #PIPE_ACCESS_INBOUND | #FILE_FLAG_OVERLAPPED, #PIPE_TYPE_BYTE | #PIPE_READMODE_BYTE | #PIPE_NOWAIT, 1, MemSize, MemSize, #NMPWAIT_USE_DEFAULT_WAIT, #Null)
SaveImage(Image, PipeName$, Format, Compression)
ReadFile_(ImageDataPipe, *Mem, MemSize, *MemSize, #Null)
CloseHandle_(ImageDataPipe)
ProcedureReturn *Mem
EndProcedure
mpz
Beiträge: 505 Registriert: 14.06.2005 15:53
Computerausstattung: Win 11 Pro, 48 GB Ram, Intel I7 CPU und RX4070 Grafikkarte, PB (4/5) 6.12LT
Wohnort: Berlin, Tempelhof
Beitrag
von mpz » 25.04.2009 22:04
Hi cxAlex,
der Code sieht gut aus. Wie genau wende ich Ihn den Code praktisch an? Ich weis nicht wie ich den Wert "*MemSize" ermitteln muss den ich der Prozedur übergebe. Wenn ich meine Code durch Deinen ersetze kommt immer eine Fehlermeldung in der folgender Zeile:
> ReadFile_(ImageDataPipe, *Mem, MemSize, *MemSize, #Null) > invalid memory access
Mein Code zur Übergabe eines Image in einen Speicherbereich:
Code: Alles auswählen
w = ImageWidth(Img)
h = ImageHeight(Img)
hBmp = ImageID(Img)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = w
If direction = 0
bmi\bmiHeader\biHeight = h ; -h dreht das Bild als Textur
Else
bmi\bmiHeader\biHeight = -h
EndIf
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
width = w
height = h
bitcount = 32 ; Should be 24 bits for this example
; Rows need to be a multiple of 4 bytes so calculate extra bytes needed
extrabytesperrow = (4 - (width * bitcount / 8) % 4) % 4
; Allocate memory for bitmap
sizeheaders = SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER)
sizeimage = (width * bitcount / 8 + extrabytesperrow) * height
*bitmap = AllocateMemory(sizeheaders + sizeimage)
If *bitmap = 0
ProcedureReturn #False
;Debug("Couldn't allocate memory for bitmap")
;End
EndIf
; Set bitmap headers
*bitmapfile.BITMAPFILEHEADER = *bitmap
*bitmapfile\bfType = Asc("B") + Asc("M") << 8
*bitmapfile\bfSize = sizeheaders +sizeall
*bitmapfile\bfOffBits = sizeheaders
*bitmapinfo.BITMAPINFOHEADER = *bitmap + SizeOf(BITMAPFILEHEADER)
*bitmapinfo\biSize = SizeOf(BITMAPINFOHEADER)
*bitmapinfo\biWidth = width
*bitmapinfo\biHeight = height
*bitmapinfo\biPlanes = 1
*bitmapinfo\biBitCount = bitcount
*bitmapinfo\biCompression = 0
*bitmapinfo\biSizeImage = sizeimage
*bitmapdata = *bitmap + sizeheaders
; Create 24 bit image in bitmap
*bitmapdatapos = *bitmapdata
hDC = StartDrawing( ImageOutput(Img) )
If GetDIBits_(hDC, hBmp, 0, h, *bitmapdatapos , bmi, #DIB_RGB_COLORS)
StopDrawing()
Else
StopDrawing()
EndIf
Working on
- LibSGD - MP3D Engine -