Hi Jungs!
Wer hat denn gerade mal eine entsprechende Routine auf Lager, mit der ich ein mit [c]LoadImage()[/c] geladenes Image in einen Speicherbereich kopieren kann, aus dem ich dann später Pixel für Pixel die Farben wieder auslesen kann?
Ich will dafür aber unbedingt keine API verwenden, weil das Programm auch unter Linux laufen sollte.
Image in Speicherbereich kopieren, aber ohne API
- NicTheQuick
- Ein Admin
- Beiträge: 8812
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Zuerstmal:Ich hab keine Lösung gefunden
(nich, dat jetzt alle aufhören zu denken
)
Ich hab allerdings mal ein bisschen rumprobiert und kann euch nun zusichern, dass folgende 9 Versionen NICHT funktionieren.
Wenn einige Beispiele jeglicher Logik entsagen bitte nicht wundern, manche waren Verzweiflungsversuche (ich brauch das nämlich auch gerade ganz dringend)
Achja, meine Version versucht es genau andersrum (schreiben statt lesen), das sollte aber ja eigentlich auch funktionieren, wenn das lesen funktioniert.
(nich, dat jetzt alle aufhören zu denken
Ich hab allerdings mal ein bisschen rumprobiert und kann euch nun zusichern, dass folgende 9 Versionen NICHT funktionieren.
Code: Alles auswählen
Structure THEBITMAPINFO
bmiHeader.BITMAPINFOHEADER
bmiColors.RGBQUAD[1]
EndStructure
Structure color
blue.b
green.b
red.b
leer.b
EndStructure
Global State.l
Global bildlang.l
Global bildhoch.l
Dim Punkt1.color(300,300)
Dim Punkt2.color(300,300)
Dim Adressen.l(1)
Procedure RealRound(zahl.f);Rundet den Wert nach der nächsten ganzzahl
If zahl=>0
If zahl-Round(zahl,0)>0.5
Endzahl.l=Round(zahl,1)
Else
Endzahl.l=Round(zahl,0)
EndIf
Else
If zahl-Round(zahl,0)>0.5
Endzahl.l=Round(zahl,0)
Else
Endzahl.l=Round(zahl,1)
EndIf
EndIf
ProcedureReturn Endzahl
EndProcedure
Procedure SetDIBits(image.l,buffer.l,laenge)
;1. Version geht nicht
; bild=UseImage(image)
; CopyMemory(buffer,bild,laenge)
;2. Version geht nicht
; bild=UseImage(image)
; CopyMemory(buffer,bild+SizeOf(TheBitmapInfo),laenge)
;3. Version geht nicht
; UseImage(image)
; bild=StartDrawing(ImageOutput())
; CopyMemory(buffer,bild,laenge)
; StopDrawing()
;4. Version geht nicht
; UseImage(image)
; StartDrawing(ImageOutput())
; bild=ImageOutput()
; CopyMemory(buffer,bild,laenge)
; StopDrawing()
;5. Version geht nicht
; UseImage(image)
; bild=ImageOutput()
; CopyMemory(buffer, bild, laenge)
;6. Version geht nicht
; UseImage(image)
; bild=DrawingBuffer()
; CopyMemory(buffer, bild, laenge)
;7. Version geht nicht
; UseImage(image)
; StartDrawing(ImageOutput())
; bild=DrawingBuffer()
; CopyMemory(buffer, bild, laenge)
; StopDrawing()
;8. Version geht nicht
; bild=UseImage(image)
; StartDrawing(ImageOutput())
; CopyMemory(buffer,bild+SizeOf(THEBITMAPINFO),laenge)
; StopDrawing()
;9. Version geht nicht
; UseImage(image)
; bild=GetDC_(UseImage(image))
; CopyMemory(buffer,bild,laenge)
EndProcedure
Procedure Array_to_image_norm(usedimage.l,array.l,laenge.l,hoehe.l);Überträgt das array ins #usedimage
If State=0
bild=UseImage(usedimage)
paint=StartDrawing(ImageOutput())
If paint
areapicture.THEBITMAPINFO
areapicture\bmiHeader\biSize =SizeOf(THEBITMAPINFO)
areapicture\bmiHeader\biWidth=laenge
areapicture\bmiHeader\biHeight=hoehe
areapicture\bmiHeader\biPlanes=1
areapicture\bmiHeader\biBitCount=32
If SetDIBits_(paint,bild,0,hoehe,array,areapicture,#DIB_RGB_COLORS)<>0
EndIf
EndIf
StopDrawing()
Else
Debug "HI"
If SetDIBits(usedimage,array,(laenge+1)*(hoehe+1)*4)<>0
EndIf
EndIf
EndProcedure
Adressen(0)=Punkt1()
Adressen(1)=Punkt2()
For a=0 To 300
For b=0 To 300
Punkt1(a,b)\red=0
Punkt1(a,b)\green=0
Punkt1(a,b)\blue=255
Punkt2(a,b)\red=220
Punkt2(a,b)\green=0
Punkt2(a,b)\blue=0
Next
Next
bildlang=300
bildhoch=300
CreateImage(1,301,301)
State=0
Array_to_image_norm(1,Punkt1(),301,301)
If OpenWindow(1,100,100,301,321,#PB_Window_SystemMenu,"Titel")
CreateGadgetList(WindowID())
TextGadget(#PB_Any,0,0,300,20,"Button klicken :)")
ButtonImageGadget(1,0,20,301,301,UseImage(1))
Repeat
event=WaitWindowEvent()
If event=#PB_EventGadget And EventGadgetID()=1
INC State
If State>1
State=0
Debug "hi"
EndIf
Array_to_image_norm(1,Adressen(State),301,301)
SetGadgetState(1,UseImage(1))
EndIf
Until event=#WM_CLOSE
CloseWindow(1)
EndIf
End Wenn einige Beispiele jeglicher Logik entsagen bitte nicht wundern, manche waren Verzweiflungsversuche (ich brauch das nämlich auch gerade ganz dringend)
Achja, meine Version versucht es genau andersrum (schreiben statt lesen), das sollte aber ja eigentlich auch funktionieren, wenn das lesen funktioniert.
Falsch zugeordnetes Zitat des Tages: "O'zapft is" - Edward Snowden 
- NicTheQuick
- Ein Admin
- Beiträge: 8812
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Hier ist der Code, den ich entsprechend schneller machen will.
Er liest Zeile für Zeile, Pixel für Pixel aus einem Image aus, rechnet die Farbwerte zwischen 0 und 255 in Werte zwischen 0 und 1 um und speichert sie in einem Speicherbereich. Das Bild braucht danach 3 mal mehr Speicher als vorher. Aber das ist nicht das Problem.
Er liest Zeile für Zeile, Pixel für Pixel aus einem Image aus, rechnet die Farbwerte zwischen 0 und 255 in Werte zwischen 0 und 1 um und speichert sie in einem Speicherbereich. Das Bild braucht danach 3 mal mehr Speicher als vorher. Aber das ist nicht das Problem.
Code: Alles auswählen
Structure RTColor3F
r.f
g.f
b.f
EndStructure
Structure RTSize
x.l
y.l
EndStructure
Structure RTTexture
Size.RTSize
Gamma.f
*Img
EndStructure
NewList RTTexture.RTTexture()
Procedure.l RTLoadTexture(File.s)
Protected ID.l, *mem, Width.l, Height.l, *ImgPos, x.l, y.l, *Pixel.RTColor3F, RGB.l
ID = LoadImage(#PB_Any, File)
If ID
Width = ImageWidth()
Height = ImageHeight()
*mem = AllocateMemory(Width * Height * SizeOf(RTColor3F))
If *mem = 0 : FreeImage(ID) : ProcedureReturn #False : EndIf
If AddElement(RTTexture())
RTTexture()\Size\x = Width
RTTexture()\Size\y = Height
RTTexture()\Img = *mem
;================== ||
;= WICHTIGER TEIL = ||
;================== \/
UseImage(ID)
If StartDrawing(ImageOutput())
*Pixel = *mem
For y = 1 To Height
For x = 1 To Width
RGB = Point(x, y)
*Pixel\r = Red(RGB) / 255
*Pixel\g = Green(RGB) / 255
*Pixel\b = Blue(RGB) / 255
*Pixel + SizeOf(RTColor3F)
Next
Next
StopDrawing()
EndIf
;================== /\
;= WICHTIGER TEIL = ||
;================== ||
ProcedureReturn @RTTexture()
Else
FreeMemory(*mem)
FreeImage(ID)
EndIf
FreeImage(ID)
EndIf
ProcedureReturn #False
EndProcedure
UseJPEGImageDecoder()
RTLoadTexture("f:\avatar.jpg")