|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Ben
Anmeldungsdatum: 24.09.2018 Beiträge: 5
|
Verfasst am: 29.09.2018, 21:35 Titel: BMP Dateien in Exe mit einbinden? |
|
|
Nabend, ich spiele gerade etwas mit Bload und bmp Dateien rum im Screen 12 Modus.
Gibt es eigentlich eine relativ einfache Möglichkeit die bmp Dateien beim Compilern mit in die Exe einzubinden um nicht viele Lose Datein mit zur Exe liefern zu müssen?
Mfg. Ben |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
|
Nach oben |
|
|
Ben
Anmeldungsdatum: 24.09.2018 Beiträge: 5
|
Verfasst am: 29.09.2018, 23:55 Titel: |
|
|
Ok, das sieht schonmal sehr interessant aus, ich habe das mal getestet, leider wirft der Compiler nur Fehler.
Code: | bmp.rc
#DEFINE bmp1 1
bmp1 BINTYP DISCARDABLE "2.bmp" |
Code: | main.bas
#DEFINE bmp1 1
Dim As HWND hRes
Dim As ZString Ptr pData
hRes = LoadResource(getmodulehandle(null), FindResource(hInstance,MAKEINTRECOURCE(bmp1),"BINTYP"))
pData = LockResource(hRes)
BLOAD pData |
Fehler werden Folgende ausgegeben:
Zitat: | Command executed:
"fbc.exe" "FBIDETEMP.bas" bmp.rc -lang fblite -s gui
Compiler output:
FBIDETEMP.bas(2) error 14: Expected identifier, found 'HWND'
Dim As HWND hRes
^
FBIDETEMP.bas(4) error 71: Array not dimensioned, before '('
hRes = LoadResource(getmodulehandle(null), FindResource(hInstance,MAKEINTRECOURCE(bmp1),"BINTYP"))
^
FBIDETEMP.bas(5) error 71: Array not dimensioned, before '('
pData = LockResource(hRes)
^
FBIDETEMP.bas(5) warning 4(1): Suspicious pointer assignment
FBIDETEMP.bas(6) error 57: Type mismatch, at parameter 1 of BLOAD()
BLOAD pData
^
Results:
Compilation failed
System:
FBIde: 0.4.6
fbc: FreeBASIC Compiler - Version 1.05.0 (01-31-2016), built for win32 (32bit)
OS: Windows NT 6.2 (build 9200)
|
Achja, auch wenn ich die Optionen -lang fblite -s gui raus lasse, gibts Fehler.
Mfg. Ben |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 30.09.2018, 04:29 Titel: |
|
|
In dem Tutorial fehlen einige kleine, aber nicht ganz unbedeutende Details:
- Das Resourcenskript muß denselben Namen haben wie die Code-Datei, nur mit der Endung ".rc".
- Wenn du die Windows - API benutzen möchtest, mußt du die "windows.bi" einbinden.
Außerdem hast du dich bei "MAKEINTRESOURCE" vertippt.
resource.rc: Code: | #DEFINE bmp1 1
bmp1 BINTYP DISCARDABLE "2.bmp" |
resource.bas: Code: | #Include "windows.bi"
#DEFINE bmp1 1
Dim As HWND hRes
Dim As UByte Ptr pData
hRes = LoadResource(getmodulehandle(null), FindResource(null,MAKEINTRESOURCE(bmp1),"BINTYP"))
pData = LockResource(hRes)
Print pdata
If pdata Then
For x As UByte Ptr = pData To pData + 200
Print Hex(*x,2);" ";
Next
EndIf
Sleep |
Das Programm sollte die ersten 200 Bytes deiner Resource ausdrucken (Vergleich mit Hex-Editor).
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 30.09.2018, 18:27 Titel: |
|
|
grindstone hat Folgendes geschrieben: | Das Resourcenskript muß denselben Namen haben wie die Code-Datei, nur mit der Endung ".rc" | Nein, das sollte nicht der Fall sein.
Als weitere kleinere Verbesserung würde ich empfehlen die resource-IDs in eine separate Datei auszugliedern, die dann sowohl von FreeBasic als auch der Resourcen Datei verwendet werden kann.
resources.rc: Code: | #include "resource_ids.h"
bmp1 BINTYP DISCARDABLE "2.bmp" |
resource_ids.h
application.bas Code: | #Include "windows.bi"
#include "resource_ids.h"
Dim As HWND hRes
Dim As UByte Ptr pData
hRes = LoadResource(getmodulehandle(null), FindResource(null,MAKEINTRESOURCE(bmp1),"BINTYP"))
pData = LockResource(hRes)
'... |
_________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 01.10.2018, 01:47 Titel: |
|
|
St_W hat Folgendes geschrieben: | grindstone hat Folgendes geschrieben: | Das Resourcenskript muß denselben Namen haben wie die Code-Datei, nur mit der Endung ".rc" | Nein, das sollte nicht der Fall sein. | Stimmt, da bin ich ein Opfer meiner IDE (FbEdit) geworden. Dort wird eine Resourcendatei nur dann automatisch eingebunden, wenn sie denselben Namen wie die Sourcedatei hat. Ansonsten muß der Name der Resourcendatei explizit auf der Kommandozeile (bzw. in den Build - Optionen) angegeben werden.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
Ben
Anmeldungsdatum: 24.09.2018 Beiträge: 5
|
Verfasst am: 03.10.2018, 12:22 Titel: |
|
|
So, Tage weiter und etliches weniger an Gehirnschmalz, bin ich meiner Lösung leider nicht viel weiter gekommen.
Mein Code Sieht nun wie folgt aus:
Code: | #Include "windows.bi"
#DEFINE bmp1 13
Dim As HWND hRes
Dim As UByte Ptr pData
Screen 12
hRes = LoadResource(getmodulehandle(null), FindResource(null,MAKEINTRESOURCE(bmp1),"BINTYP"))
pData = ImageCreate(640, 480)
pData = LockResource(hRes)
Print pdata
If pdata Then
For x As UByte Ptr = pData To pData + 200
Print Hex(*x,2);" ";
Next
EndIf
Print " "
Dim As UByte Ptr bild
bild = ImageCreate(640,480)
BLOAD "2.bmp", bild
Print bild
If bild Then
For x = bild To bild + 200
Print Hex(*x,2);" ";
Next
EndIf
bild = pdata
put (0,0), bild, Pset
Sleep |
Die Angabe in der Rescource Datei zum Bild habe ich nun schon mit allen Möglichen methoden versucht. Mit Direktem Pfad, ohne, Direkt auf C:
Leider unterscheiden sich schon die Hex Angaben von dem Was pdata liefert und dem was die bmp Datei liefert.
Ausgabe:
Code: | 4436072
42 4D 76 58 02 00 00 00 00 00 76 00 00 00 28 00 00 00 80 02 00 00 E0 01 00 00 01 00 04 00 00 00 00 00 00 58 02 00 C4 0E 00 00 C4 0E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 0F FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
35274336
01 14 E0 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
@St_W das Auslagern dürfte dann nur der Übersichtlichkeit dienen? |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 03.10.2018, 15:02 Titel: |
|
|
Auf der sicheren Seite bist du, wenn sich die Bitmap - Datei im selben Verzeichnis befindet wie der Quellcode. Außerdem muß das Bitmap dieselbe Farbtiefe haben wie der Bildschirm.
Das Übertragen der Resourcendaten in ein Image ist leider nicht ganz so einfach. Zum einen hat die .bmp - Datei einen Header, der sich von dem des Image unterscheidet.
https://de.wikipedia.org/wiki/Windows_Bitmap
Zum anderen ist der Bildinhalt nicht unbedingt 1:1 übertragbar.
https://www.freebasic-portal.de/befehlsreferenz/interne-pixelformate-464.html
Hier ist insbesondere der "Pitch" - Wert zu beachten, der dafür sorgt, daß die Länge einer Bildzeile immer ein Vielfaches von 4 ist. Die Pixeldaten müssen also entsprechend umgerechnet werden.
Meine Empfehlung: Schreib dir erst einmal eine Programmsequenz, die den Header der .bmp - Datei auswertet und die ermittelten Werte sauber auflistet. Nach diesen Werten (Breite, Höhe, Farbtiefe etc.) kannst du das Programm dann ein passendes Image erstellen lassen und den Bildinhalt (unter Berücksichtigung des Pitch - Wertes) per Pointerindizierung übertragen.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
Ben
Anmeldungsdatum: 24.09.2018 Beiträge: 5
|
Verfasst am: 03.10.2018, 16:28 Titel: |
|
|
grindstone hat Folgendes geschrieben: | Auf der sicheren Seite bist du, wenn sich die Bitmap - Datei im selben Verzeichnis befindet wie der Quellcode. Außerdem muß das Bitmap dieselbe Farbtiefe haben wie der Bildschirm.
Das Übertragen der Resourcendaten in ein Image ist leider nicht ganz so einfach |
Ok, erstes war / ist gegeben, damit hatte ich schon rumgespielt.
Zweites macht mir dann jetzt einiges klar.
Mal anders gedacht, wenn ich das bmp Bild per BLOAD Lade und anzeigen lasse, dann müsste ich doch theoretisch den Bildschirminhalt Binary auslesen können und in eine Datei schreiben? Diese müsste dann eigentlich ladbar sein, oder habe ich da am ende einen Denkfehler?
Wenn nein, mit welchen Befehlen kann ich den Bildschirm Binary auslesen?
EDIT: Ok Gerade in der Referenz mit GET (x,y) -STEP (x,y), Puffer sollte ich die benötigten Daten bekommen?
EDIT2: Ok das ging so wie ich mir das dachte stark in die Hose
Code: | Dim AS UByte Ptr pdata
Dim As UByte Ptr bild
ScreenRes 640,480,24
bild = ImageCreate(640,480)
pdata = ImageCreate(640,480)
BLOAD "2.bmp", bild
put (0,0), bild, Pset
sleep
get (0,0) -STEP (640,480),pdata
CLS
put (0,0),pdata
SLEEP |
Da wird bei put data leider nur nen Rosa Vollbild angezeigt. Wo habe ich da nen Denkfehler? |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 03.10.2018, 21:42 Titel: |
|
|
Code: | get (0,0) -STEP (639,479),pdata |
Das Bild ist 640px breit, das sind die Maße von 0 bis 639. Wenn du mehr Daten in den Speicher liest, als dort Platz hat, ist das ... ungünstig.
Du kannst übrigens auch gleich aus einem Bildspeicher heraus in einen anderen Bildspeicher kopieren. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 04.10.2018, 05:04 Titel: |
|
|
Ben hat Folgendes geschrieben: | Mal anders gedacht, wenn ich das bmp Bild per BLOAD Lade und anzeigen lasse, dann müsste ich doch theoretisch den Bildschirminhalt Binary auslesen können und in eine Datei schreiben? Diese müsste dann eigentlich ladbar sein, oder habe ich da am ende einen Denkfehler? | Das ist zwar etwas um die Ecke gedacht (soll heißen: Die Idee könnte glatt von mir sein ), aber ja, es geht.
Dazu mußt du zuerst mit einem kleinen Hilfsprogramm die Resourcendatei erstellen: Code: | ScreenRes 640,480,32 '<------- Bildschirm muß dieselbe Farbtiefe haben wie das Bitmap
Dim As Any Ptr bild = ImageCreate(30,30) '<--- Größenangabe auf das bmp anpassen
BLoad "2.bmp", bild
Dim As Integer ImagePtr, Breite, Hoehe, bpp, Pitch, Groesse
Dim As UByte Ptr Pixdata
ImageInfo bild, Breite, Hoehe, bpp, Pitch, Pixdata, Groesse
BSave "2.dat", Pixdata, Groesse |
Das Resourcenskript muß jetzt natürlich auf die neue Datei "2.dat" verweisen. Code: | #Include "windows.bi"
#DEFINE bmp1 13
Dim As HWND hRes
Dim As UByte Ptr pData
hRes = LoadResource(getmodulehandle(null), FindResource(null,MAKEINTRESOURCE(bmp1),"BINTYP"))
pData = LockResource(hRes)
ScreenRes 640,480,32
Dim As Any Ptr pd, bild = ImageCreate(30,30) 'das image muß dieselben dimensionen haben wie das die umgewandelte .bmp - datei
ImageInfo bild,,,,,pd 'pointer auf den anfang der bilddaten
'pixeldaten in image übertragen
For x As Integer = 0 To *Cast(ULong Ptr, pdata + 1) - 1
' \_________________________/ bytes 1 bis 4 enthalten die längeninformation des datenblocks
Cast(UByte Ptr, pd)[x] = pdata[x + 5]
Next
Put (10, 10), bild, PSet 'image auf bildschirm
? "OK"
Sleep |
Es geht auch noch einfacher, allerdings bin ich mir nicht sicher, ob dann Schreibzugriffe auf den Imagespeicher nicht die Speicherverwaltung von FB durcheinanderbringen. Wenn du allerdings nur lesend auf das Bild zugreifst, dürfte es keine Probleme geben:
Resourcendatei erstellen: Code: | ScreenRes 640,480,32 '<------- Bildschirm muß dieselbe Farbtiefe haben wie das Bitmap
Dim As Any Ptr bild = ImageCreate(30,30) '<--- Größenangabe auf das bmp anpassen
BLoad "2.bmp", bild
Dim As Integer ImagePtr, Breite, Hoehe, bpp, Pitch, Groesse
Dim As UByte Ptr Pixdata
ImageInfo bild, Breite, Hoehe, bpp, Pitch, Pixdata, Groesse
BSave "2.dat", bild, Groesse + 32 'header + pixeldaten |
auf Resource zugreifen: Code: | #Include "windows.bi"
#DEFINE bmp1 13
Dim As HWND hRes
Dim As UByte Ptr pData
hRes = LoadResource(getmodulehandle(null), FindResource(null,MAKEINTRESOURCE(bmp1),"BINTYP"))
pData = LockResource(hRes)
ScreenRes 640,480,32
Put (10, 10), pData + 5, PSet 'gespeicherte binärdaten
? "OK"
Sleep |
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
Ben
Anmeldungsdatum: 24.09.2018 Beiträge: 5
|
Verfasst am: 22.10.2018, 20:18 Titel: |
|
|
So nach langem komme ich endlich wieder zu meinem Problem.
Ok, mit der BSAVE Variante habe ich nun das Problem, das 1. die Farben komisch wiedergegeben wird und zweitens das ganze Bild um gute 10px nach rechts und Links versetzt werden.
Also ich habe mir zum erstellen folgendes geschrieben.
Code: |
' Aufruf MakeRes 2.bmp 640 480 4
DIM AS STRING FILE = EXEPATH + "\" + COMMAND(1)
DIM AS STRING FILENAME = MID(COMMAND(1),1,LEN(FILE) -4)
DIM AS STRING SAVEFILE = mid(FILE,1,LEN(FILE)-3) + "dat"
DIM AS INTEGER X = VALINT(COMMAND(2))
DIM AS INTEGER Y = VALINT(COMMAND(3))
DIM AS INTEGER D = VALINT(COMMAND(4))
DIM Pic AS Any PTR
Dim PicS As Any PTR
ScreenRes X,Y,D
Pic = ImageCreate(X,Y,D)
PicS = ImageCreate(X,Y,D)
BLOAD FILE, Pic
PUT(0,0), Pic, PSET
SLEEP 1000
SCREENLOCK
GET (0,0) -Step(X-1,Y-1),PicS
SCREENUNLOCK
CLS
Print "Gelesen"
Sleep 1000
PUT(0,0),PicS, PSET
Sleep 1000
CLS
PRINT "Warte"
Sleep 1000
CLS
For i AS UByte Ptr = Pic to Pic + 2000
Print HEX(*i,2); " ";
sleep 5
Next i
sleep
|
Wie kann ich denn Brutal das ganze Byte für Byte in eine Datei speichern ohne BSAVE? Wie kann ich 1. die daten Binary Byte für Byte aus dem ptr auslesen? mit *PicS will ich ja gleich den ganzen Wert auf einmal haben?
Ich denke ich kann das ganze Wohl wie ein Array behandeln? Sprich mit PicS(1) usw... ? Wie erfahre ich wo der letzte Index liegt?
Das Auslesen mit der Hex Methode führt auch nicht wirklich zum Erfolg, bzw. kann nicht hinhauen denn nach ca 5 Bytes wird nur noch 00 oder FF ausgegeben, was nicht wirklich hinkommen kann?!
Diese Infos habe ich leider noch nicht gefunden... |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 23.10.2018, 13:55 Titel: |
|
|
Ben hat Folgendes geschrieben: | das ganze Bild um gute 10px nach rechts und Links versetzt | "It's not a bug, it's a feature"
Der Versatz war Absicht, wenn du das Bild ganz in der Ecke haben wilst, mußt du Code: | Put (10, 10), bild, PSet 'image auf bildschirm | durch Code: | Put (0, 0), bild, PSet 'image auf bildschirm | ersetzen.
Zitat: | Wie kann ich denn Brutal das ganze Byte für Byte in eine Datei speichern ohne BSAVE? | Warum einfach, wenn's auch kompliziert geht? Aber bitte: Vielleicht kommt dir bei der Analyse der Programmzeilen ja die eine oder andere Erleuchtung Code: | ' Aufruf MakeRes 2.bmp 640 480 4
DIM AS STRING FILE = EXEPATH + "\" + COMMAND(1)
DIM AS STRING FILENAME = MID(COMMAND(1),1,LEN(FILE) -4)
DIM AS STRING SAVEFILE = mid(FILE,1,LEN(FILE)-3) + "dat"
DIM AS INTEGER X = VALINT(COMMAND(2))
DIM AS INTEGER Y = VALINT(COMMAND(3))
DIM AS INTEGER D = VALINT(COMMAND(4))
DIM Pic AS Any PTR
Dim PicS As Any PTR
ScreenRes X,Y,D
Pic = ImageCreate(X,Y,D)
PicS = ImageCreate(X,Y,D)
BLOAD FILE, Pic
PUT(0,0), Pic, PSET
SLEEP 1000
SCREENLOCK
GET (0,0) -Step(X-1,Y-1),PicS
SCREENUNLOCK
CLS
Print "Gelesen"
Sleep 1000
PUT(0,0),PicS, PSET
Sleep 1000
'****************************************
Dim As Integer Breite, Hoehe, bpp, Pitch, Groesse
ImageInfo PicS, Breite, Hoehe, bpp, Pitch, Pixdata, Groesse
Kill SAVEFILE
Open SAVEFILE For Binary As #1
Put #1, ,Cast(UByte Ptr,PicS)[0], Groesse + 32
Close 1
'****************************************
CLS
PRINT "Warte"
Sleep 1000
CLS
For i AS UByte Ptr = Pic to Pic + 2000
Print HEX(*i,2); " ";
sleep 5
Next i
sleep |
Da hier die Längeninformation von BSAVE fehlt, muß es statt Code: | Put (0, 0), pData + 5, PSet 'gespeicherte binärdaten | heißen: Code: | Put (0, 0), pData, PSet 'gespeicherte binärdaten |
Und nochmal: Ressourcenbild und Bildschirm müssen die gleiche Farbtiefe haben.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
UEZ
Anmeldungsdatum: 24.06.2016 Beiträge: 129 Wohnort: Opel Stadt
|
Verfasst am: 17.01.2019, 23:57 Titel: |
|
|
Ich benutze für solche Zwecke "FB File2Bas Code Generator", um Dateien mit in die Exe einzubinden. Wenn du Dateien einfach per Drag'n'Drop auf die GUI ziehst, generiert das Skript den entsprechenden FB code, den du in den Editor kopieren kannst oder du benutzt ihn per #include.
Hier ein Beispiel, um eine DLL mit einzubetten: Play nostalgic C64 sounds v1 + v2 oder ein Bild auf die Platte zu extrahieren, welches eingebettet ist: Water Effect
Wenn du nur mit Windows arbeitest, kannst du das Bild einbetten und direkt aus dem Speicher laden, ohne vorher auf die Platte zwischen zu speichern.
Beispiel: The Matrix v1.41 [Windows only] _________________ Gruß,
UEZ |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|