Autor Beitrag
Killian2004
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 72

Vista Business x64
Delphi 7 Ent. RAD Studio 2009
BeitragVerfasst: Fr 26.02.10 20:10 
Servus,

ich habe die Forumsuche geknechtet, aber bin in der Hinsicht nicht fündig geworden. Sollte ich dennoch einen konstruktiven Beitrag übersehen haben, dann bitte einfach den Link posten. Danke


Mein Ziel ist es ein Bitmap bzw. ein *.png File (24Bit + Alphakanal) vor Verfremdung zu schützen. Damit meine ich eventuelle Veränderungen meiner, mit einem Programm mitgelieferten, Bilder ausschließen zu können. Die Bilder liegen in Ordner der Anwendung, nur als reine Bilder kann sie ja jeder im Gimp o.A. öffnen und manipulieren.

Daher dachte ich, es wäre vielleicht eine gute Idee, die Bilder in eine Binärdatei zu schreiben. Das brachte mir gedanklich auch den Vorteil, dass ich anwendungsspezifische Informationen zu dem jeweiligen Bild (quasi die "Meta"-Infos) gleich mit in diese Binärdatei schreiben kann.

Kurz um, ich habe Text ohne Probleme binär abspeichern können, auch typisierte Dateien mit "Records" funktionieren tadellos. Versuche ich aber ein TBitmap in einem Record zu speichern, dann bekomme ich beim Lesen der Datei eine Fehlermeldung. Wenn ich das Bitmap noch einmal explizit initialisiere, dann bleibt der Fehler aus, aber dafür ist das Bild natürlich leer.


Daher stellen sich mir folgenden Fragen:
1. Ist es prinzipiell überhaupt möglich, Bilddateien so umzuwandeln und sie dann einem TBitmap bzw. TPngImage zu übergeben?
2. Macht die Überlegung Sinn, oder ist das Schreiben von Bildern in Binärdateien Unfug?
3. Wenn 2. sinnfrei ist, welche Alternativen gäbe es?


Ich hoffe meine Erläuterungen sind plausibel, bisweilen neige ich zu dem Eingeständnis, mich etwas kompliziert auszudrücken :roll:
Gruß, Killian

_________________
Die Antwort ist 17, aber wie lautet die Frage?
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Fr 26.02.10 20:24 
du könntest zum Beispiel durch die Anpassung von R/G/B/A - Wert auf Gerade/Ungerade einen Bitcode in die Datei einfügen, ohne dass man nennenswerte Farbunregelmäßigkeiten erkennen könnte.
Killian2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 72

Vista Business x64
Delphi 7 Ent. RAD Studio 2009
BeitragVerfasst: Fr 26.02.10 20:46 
Ja, das wäre eine Möglichkeit, das File unique zu machen. Aber das ist nicht meine Absicht.
Okay, ich denke es liegt doch wieder an meiner Formulierung :?

Mir bereitet exakt das Schreiben in die Binärdatei das Problem.
Ich habe das ganze jetzt erstmal mit einer *.ico versucht und wollte dieses dann dem TIcon der Form1 zuweisen.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure ffxInitialize(path_: string; form_: TForm);
begin
 ffxRootPath := path_;
 ffxGameForm := form_;

 {CPF = Cataclysm Parameter File}
 assignFile(ffxAppFile, ffxRootPath + 'params.cpf');
 if fileExists(ffxRootPath + 'params.cpf'then
  reset(ffxAppFile)
 else
  rewrite(ffxAppFile);

 seek(ffxAppFile, 0);
 read(ffxAppFile, ffxAppParams);
 closeFile(ffxAppFile);

 ffxGameForm.caption := ffxAppParams.title + ' ' + ffxAppParams.version;
 ffxGameForm.icon.assign(ffxAppParams.icon);
end;


wobei der Typ ffxAppParams wie folgt deklariert ist:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  { CONTAINERS }
  TFFXAppParams = packed record
    title: shortstring;
    version: shortstring;
    icon: TIcon;
  End;


Die Binärdatei ist so deklariert

ausblenden Delphi-Quelltext
1:
2:
  { FILES }
  ffxAppFile: file of TFFXAppParams;



Leider funktioniert das nicht. Die Datei ist vorhanden, ich habe sie initial einmal per "write" erstellt.
Wenn ich den Code compilieren will, dann bricht es ab und wirft eine EAccessViolation.
Das sagt mir allerdings erstmal nichts, so weit reichen meine Programmierkenntnisse dann leider doch nicht.

Ich habe also das Problem zu lösen, ein Bild (*.bmp, *.png) in eine Binärdatei zu schreiben. Diese kann, wenn ich das Prinzip richtig verstanden habe, ja niemand lesen, wenn er das vorliegende Konstrukt nicht kennt.

Freue mich über jede Hilfestellung!
Gruß, Killian

_________________
Die Antwort ist 17, aber wie lautet die Frage?
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Fr 26.02.10 20:50 
Du könntest sie mit einem Filestream lesen und dann im nächsten Schritt in einen zweiten Filestream schreiben.
Killian2004 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 72

Vista Business x64
Delphi 7 Ent. RAD Studio 2009
BeitragVerfasst: Fr 26.02.10 21:32 
Okay, ich habe jetzt versucht das mit den von dir angesprochenen TStreams zu lösen.
Das Prinzip ist ja in etwa das gleiche wie mit einem file of.

Doch auch hier bekomme ich beim Versuch, das Icon dann zu lesen, die gleiche EAccessViolation.
Beim Schreiben des Records passiert kein Fehler, es bricht erst ab, wenn ich versuche die Daten zu lesen und dem Icon der Form1 zuzuweisen.

Seltsamerweise funktioniert es aber, wenn ich vorher jedesmal die Datei erst schreibe. Dort wird auch das Icon initial mit einer *.ico geladen.
Das soll ja aber dann nach dem 1.Mal nicht mehr nötig sein, sondern dann soll das FormIcon aus der Datei gelesen werden, in die mein Record geschrieben wurde.

Eine Idee, was ich falsch mache?
Gruß, Killian

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Vielleicht hat jemand einen Link oder Hinweis zur generellen Funktionsweise. Also wie funktioniert das Speichern eines *.png in eine Binärdatei?
Nochmal zur Veranschaulichung, was ich meine:

Beispiel

Das funktioniert mit Strings und Integers wunderbar, nur bei Bildern respektive Objekten funktioniert es nicht mit obigen Code.
Am Ende soll das natürlich auch umkehrbar sein, so dass ich aus der Binärdatei bequem das Record erstellen und dort auf das Bildobjekt zugreifen kann.

Hoffe, das ist in dieser Art irgendwie realisierbar.
Gruß, Killian

Moderiert von user profile iconNarses: Bild als Anhang hochgeladen.
Einloggen, um Attachments anzusehen!
_________________
Die Antwort ist 17, aber wie lautet die Frage?
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Sa 27.02.10 12:30 
ich vermute mal, dass du die Binärdatei bei jeder Verwendung zuerst wieder in zwei temporäre Dateien [PNG, Meta]aufsplitten musst und diese dann separat Laden musst um auf das Bild zuzugreifen. Ansonsten müsste man sich mal durch den Source von TPNGimage arbeiten, oder, je nach Zeit und Lust PNG selbst implementieren um aus einem Bytearray eine solche Datei zu erstellen.

Man könnte natürlich auch auf Algorithmen wie .zip zurückgreifen...
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10184
Erhaltene Danke: 1259

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 27.02.10 13:28 
Moin!

user profile iconKillian2004 hat folgendes geschrieben Zum zitierten Posting springen:
Okay, ich habe jetzt versucht das mit den von dir angesprochenen TStreams zu lösen.
Das Prinzip ist ja in etwa das gleiche wie mit einem file of.

Doch auch hier bekomme ich beim Versuch, das Icon dann zu lesen, die gleiche EAccessViolation.
[...]
Das funktioniert mit Strings und Integers wunderbar, nur bei Bildern respektive Objekten funktioniert es nicht mit obigen Code.
Das liegt daran, dass du in dem Record nur den Zeiger auf den Speicher, an dem das Objekt auf dem Heap liegt, speicherst (das erklärt dann auch, warum das manchmal klappt, wenn man im selben Programm vorher ein entsprechendes Bild angelegt hat - die Daten liegen dann noch auf dem Heap). Es ist aber noch schlimmer: die Bilddaten liegen auch nicht im Speicherbereich des Objekts, sondern ebenfalls irgendwo anders im RAM. Etwas ausführlicher gibt´s das Ganze hier in der Lib (geht da zwar um Netzwerkdatenübertragung, aber ob ich einen Stream ins Netz oder auf die Platte schreibe, ist erstmal für das Konzept egal).

Du kannst an die Bilddaten bei einem Bitmap über das .Scanlines[]-Array rankommen, bei einem PNG-Bild wird das nicht klappen, die Daten werden vermutlich komprimiert im Speicher gehalten. Hier kannst du aber vermutlich die Methode .SaveToStream der TPNGImage-Klasse verwenden. :idea: Geht natürlich auch bei einem Bitmap, einfach mit der Methode in den Stream schreiben. Vorsicht Falle: wenn mehr als ein Element in den Stream wandern sollen, braucht man wieder ein Protokoll, also z.B. die Länge des folgenden Streams als Int davor oder so, und dann müssen die einzelnen Elemente vor dem .LoadFromStream auch erstmal in einen weitern z.B. TMemoryStream geladen werden, sonst klappt das auch nicht.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.