Laden...

Forenbeiträge von Gerwald Ingesamt 27 Beiträge

20.10.2024 - 16:37 Uhr

Ich habe leider im Forum dazu nichts gefunden.

Ich schreibe gerade einen IFF Konverter. Bei dem sind eh nach Aktion die aufgeführt wird Button aktiv oder inaktiv. Das klappe sehr gut. 
Mein Problem ist aber, es gibt auch einen Dark Mod. In dem Modus passen sich aber die inaktiven Button leider nicht an. Die bleiben auf ihre Grau. Das Problem ist halt das diese Grau für den Dark Mod zu hell ist.

Ich wäre schon glücklich wenn man die Hintergrundfarbe in eine neutralere Farbe bringen kann, die einigermaßen für bei Mod passt.  
Nur habe ich dazu zu wenig Erfahrung wie man so was machen könnte, hat bitte wer für mich ein paar Tipps, oder Code Beispiel?

24.09.2024 - 11:18 Uhr

Dort steht es auch. Für Pal 44:44

24.09.2024 - 10:35 Uhr

Sorry habe das mit der Auflösung ünersehen.

Erzeugt habe ich die Datei mit dem Picture Manager 5.5 am Amiga bei einer Auflösung von 1024 x 768 bei 24 Bit

24.09.2024 - 09:59 Uhr

Bei mir steht

X 44

Y 44.

Für was die gehören verstehe ich schon. Nur wie werden diese Werte beim erstellen der Grafik errechnet?

24.09.2024 - 07:13 Uhr

Was ich noch nicht verstehe ist wie der x und y Aspect errechnet wird.

22.09.2024 - 13:03 Uhr

Danke für dein Angebot, ich komme da sicher gerne mal zurück.

Das kann jetzt aber einige Zeit dauern.

21.09.2024 - 18:50 Uhr

Es gibt da noch einen Fehler im Code.

bitmapZaehlerBreite  und bitmapZaehlerHoehe müssen auf 0 zurück gesetzt werden bevor die Daten eines neuen Body geladen werden.

21.09.2024 - 09:31 Uhr

Ich habe mir dann eine andres Testbild gemacht, was auch Dreiecke und Kreis hat. Da konnte ich dann sehen was noch schief läuft.

Das Problem ist, das ein MC 680x0 die Byte anderes speichert als ein x86. Da ist die Bit Reihenfolge eine anderes. Aber und da bin ich auch darüber gefallen. Man muss Wissen wenn die Bit Reihenfolge im Byte umdrehen muss und wann nicht. Weil man das aber so nicht unbedingt drehen muss, bin ich nicht auf die Idee gekommen das im Body zu machen.

Klar kann ich den Code hier veröffentlichen. Ein Ziel des ganzen ist ja auch eine Doku zu schaffen die es mal genau beschreibt. 
Aber bitte bedenkt das ist der Code eines Anfängers und viele Teile sind jetzt etwas schlecht, weil da viele Versuche dahinter stehen und der Code oft verändert wurde. 
Ich habe in dir mal Angehängt.

Vielen dank noch mal für deine Hilfe. Auch wenn es jetzt nicht ganz die Lösung war, war dein Ansatz schon wichtig um zu verstehen wie die Daten da lieben.

21.09.2024 - 08:03 Uhr

Huhu jetzt klappt  es

14.09.2024 - 15:05 Uhr

Sorry, bei der BMHD hast du Recht, das hatte ich falsch im Kopf.

Es ist noch nicht perfekt. Aber der Weg stimmt. Da hat er mir den richtigen Tipp gegeben.

@Th69
Wie liegen jetzt die Daten. Vereinfacht gesagt hatten wir beide zu einen Teil recht. Es stimmt auch so wie ich es gepostet habe. Nur wenn immer gesagt wird im Amiga sind die Daten 90 Grad gedreht sieht man sie halt auch mal schnell mit dem falsch Blickwinkel an.

Sie liegen Zeilenweiße. 
Beispiel Grafik 800 x600

800 Bit mit R0, 800 Bit mit R1 .... 800 Bit mit R7, 800 Bit mir G0, 800 Bit mit G1 .... 800 Bit mit G7, 800 Bit mit B0, 800 Bit mit B1 .... 800 Bit mit B7

Ganz passte es aber noch nicht. Da muss ich mir meinen Code noch genauer ansehen. Denke da läuft ein Zähler nicht ganz richtig.

12.09.2024 - 17:59 Uhr

Ich muss gestehen für mich als Anfänger wird das immer verwirrender. Daher ist es für mich jetzt auch schwer den C Code zu verstehen. 
Vielleicht sollte ich das mal ruhen lassen und meine Kenntnisse zuerst mal vertiefen.

Ist ja voll interessant. Man sagt immer, am Amiga braucht man bei einer IFF 24 Bit Grafik 24 Befehle ( Assembler ) um die Farbe eines Pixel zu ändern. Das würde das unterstreichen wie ich am Anfang gesagt habe das die Daten liegen. Ist aber nicht so. 
Es wird aber noch besser. Wenn ich von dem Masken lesen, hört sich das für mich so an als wenn dann mehr Daten gespeichert sind. Weil ja der Maskenwert noch dazu kommt. 
Aber jetzt pass mal auf. Bei einer Grafik von 800 x 600 24 Bit mit dem Maskenwert 1. Also eine IFF Grafik wie sie zum Beispiel auch XnView erzeugt. Da ist der Body 1 440 000 Byte Groß. Bei der selben Grafik ohne Maske so wie ich das verstehe müsste der kleiner sein. Er ist aber auch 1 440 000 Byte groß. Was ja auch passt 800  * 600 * 3 = 1 440 000.

Wobei ich bei den Beschreibungen auch so meine Zweifel habe. Denn die BMHD wird zwar immer richtig beschrieben. Was aber so gut wie keiner dazu schreibt ist das die ersten zwei Byte leer sind.

Wie auch immer, ich habe jetzt noch wenn gefragt der so einen Code, wenn auch für den Amiga, schon mal geschrieben hat. Vielleicht habe ich Glück und er gibt mir Antwort.

12.09.2024 - 13:16 Uhr

Sorry das habe ich jetzt überlesen.

Wenn ich den Code nehme wo man davon ausgeht das die Grafik im Speicher gedreht ist. Also so wie ich das am Anfang gesagt habe. Bekomme ich Streifen.

12.09.2024 - 10:30 Uhr

Das ist der letzte Code. Zeilenweise gelesen.

12.09.2024 - 07:08 Uhr

Das ist das Ausgangsbild.

12.09.2024 - 07:06 Uhr

Ich glaube so falsch liegst du da gar nicht. Die KI hatte da eine ganz gute Idee und meint nimm zum Beispiel ein Bild mit Vierecken. 
In den Bild gibt es ein grünes Viereck an der oben rechten Ecke. Wenn man sich aber das Bild da angezeigt wird ansieht. Passt es zwar in der Höhe, aber nicht in der Breite. Da wiederholt das Bild. 
Ich mach einen zweiten Beitrag wo ich das Originalbild anhänge damit man den Vergleich besser sieht.

08.09.2024 - 15:04 Uhr

Ich mache mir gerade was zu essen. Dann werde ich mal die Bit drehen. Versuchen kann man es ja.

08.09.2024 - 14:43 Uhr

Ich habe jetzt das gleiche Bild auf 100 x 100 Pixel geändert. 16 x 16 war mir doch zu kleine. 
Gibt aber auch nur Datenmüll. 
Am Amiga und am PC von xnView wird es richtig angezeigt.

08.09.2024 - 13:58 Uhr

Ich habe mir jetzt mal die Einsprung Adressen angesehen, die scheinen zu passen.

HauptZähler: 798  Spaltenzähler: 798

rotByteIndex: 798
gruenByteIndex: 1598
blauByteIndex: 2398

Bitmapzähler Breite: 798
Bitmapzähler Höhe: 0

RotByte: 00, GruenByte: 00, BlauByte: 00, Index: 31F

---------------------------

HauptZähler: 799  Spaltenzähler: 799

rotByteIndex: 799
gruenByteIndex: 1599
blauByteIndex: 2399

Bitmapzähler Breite: 799
Bitmapzähler Höhe: 0

RotByte: 00, GruenByte: 00, BlauByte: 00, Index: 960

---------------------------

HauptZähler: 800  Spaltenzähler: 0

rotByteIndex: 2400
gruenByteIndex: 3200
blauByteIndex: 4000

Bitmapzähler Breite: 0
Bitmapzähler Höhe: 1

RotByte: 00, GruenByte: 00, BlauByte: 00, Index: 961

Zwei Variablen.

xxxxByteIndex zählt immer eine Zeile. Mit xxxByteArray errechne ich die neue Adresse wenn eine Zeile durchgelaufen ist.

Beispiel Bild mit 800 x 600 Pixel.

Startwert für: rotByteIndex = 0
gruenByteIndex = 800
blauByteIndex = 1600

rotByteIndex zählt  von 0 bis 799
gruenByteIndex zählt von 800 bis 1599
blauByteIndex zählt von 1600 bis 2399.

Ist die Zeile durch wird ByteArray um die Bild Breite mal 3 erhöht und auf ByteIndex übergeben.

Die Werte für die zweite Zeile sind dann

rotByteIndex = 2400
gruneByteIndex = 3200
blauByteIndex = 4000

Ja, ein Profi würde es vielleicht anderes machen.

Klar kann ich das auch mit einen kleiner Bild machen. Muss ich am PC eines in der Größe anpassen und dann am Amiga in ein IFF konvertieren.

08.09.2024 - 07:24 Uhr

Ich habe den Code jetzt angepasst. Aber so ganz passt es wohl noch nicht.

Ich habe mal die ersten Werte von RotByte, GruenByte und BlauByte  im Hex Editor verglichen. Die stimmen.
Nur das Bild wird noch nicht richtig angezeigt. Vielleicht habe ich als Anfänger da ja eine Fehler der mir nicht auffällt. 
Ich habe mal ein Bild angehängt.

// Bitmap erstellen
Bitmap flag = new Bitmap(bildBreite, bildHoehe, PixelFormat.Format24bppRgb);

using (FileStream fs = new FileStream(fileIFF, FileMode.Open, FileAccess.Read))
{
BinaryReader br = new BinaryReader(fs);

// Zu Bodydaten springen
br.BaseStream.Seek(bodyIndex + 8, SeekOrigin.Begin);

int byteBody = (bildBreite * bildHoehe * 3);
byte[] bodyData = br.ReadBytes(byteBody);

// Überprüfen, ob bodyData korrekt gelesen wurde
if (bodyData == null || bodyData.Length == 0)
{
MessageBox.Show("Body-Daten konnten nicht gelesen werden.");
return;
}

// Sprung Adresse errechnen.
hauptzaehler = bildBreite * bildHoehe;   // Hauptzähler berechnen
spaltenzaehler = 0;                      // Ist spaltenzaehler = bildBreite. ByteArray muss neu berechnet werden

rotByteArray = 0;
gruenByteArray = bildBreite;
blauByteArray = bildBreite * 2;
rotByteIndex = rotByteArray;
gruenByteIndex = gruenByteArray;
blauByteIndex = blauByteArray;

// Zähler zum zuweisen der Farben in Bitmap auf Null setzen
bitmapZaehlerBreite = 0;
bitmapZaehlerHoehe = 0;

hz = 0;         // Zähler für hauptzähler auf Null setzen

Debug.WriteLine($"Breite: {bildBreite}");
Debug.WriteLine($"Höhe: {bildHoehe}");
Debug.WriteLine($"Hauptzähler: {hauptzaehler}");

Debug.WriteLine($"\nrotByteIndex: {rotByteIndex}");
Debug.WriteLine($"gruenByteIndex: {gruenByteIndex}");
Debug.WriteLine($"blauByteIndex: {blauByteIndex}");

while (hz < hauptzaehler)
{

Debug.WriteLine($"\nHauptZähler: {hz}  Spaltenzähler: {spaltenzaehler}");

// Rot auslesen
RotByte = bodyData[rotByteIndex];

// Grün auslesen 
GruenByte = bodyData[gruenByteIndex];

// Blau auslesn für 8 Pixel
BlauByte = bodyData[blauByteIndex];

// Zuweisung der von xxxByteIndex
if (spaltenzaehler < bildBreite - 1)
{
rotByteIndex++;
gruenByteIndex++;
blauByteIndex++;
spaltenzaehler++;
}
else
{
rotByteArray = rotByteArray + (bildBreite * 3);
gruenByteArray = gruenByteArray + (bildBreite * 3);
blauByteArray = blauByteArray + (bildBreite * 3);

rotByteIndex = rotByteArray;
gruenByteIndex = gruenByteArray;
blauByteIndex = blauByteArray;

spaltenzaehler = 0;
}
hz += 1;

Debug.WriteLine($"\nBitmapzähler Breite: {bitmapZaehlerBreite}");
Debug.WriteLine($"Bitmapzähler Höhe: {bitmapZaehlerHoehe}\n");

Debug.WriteLine($"RotByte: {RotByte:X2}, GruenByte: {GruenByte:X2}, BlauByte: {BlauByte:X2}, Index: {rotByteIndex:X}\n");
Debug.WriteLine("---------------------------\n");

flag.SetPixel(bitmapZaehlerBreite, bitmapZaehlerHoehe, Color.FromArgb(RotByte, GruenByte, BlauByte));

if (bitmapZaehlerBreite < bildBreite -1)
{                       
bitmapZaehlerBreite++;
}
else
{
bitmapZaehlerBreite = 0;
bitmapZaehlerHoehe++;
}

}
}

pictureBox1.Image = flag;
}

07.09.2024 - 12:46 Uhr

Ja, HAM6 und HAM8 ist ein eigener Typ, wird auch wieder anderes gespeichert.

So wohl HAM6 und HAM8 kann man auf der Workbench nicht nutzen. Bilder die in HAM6 oder HAM8 gespeichert sind öffnen immer den passenden Screen dazu. Am Amiga kann so viel Screen offenen als in den Speicher passt. Heute würden wir vielleicht Desktop sagen. Dabei kann jeder Screen eine eigene Auflösung haben und Farbtiefe und Farbpalette. Mit dem AAA Chip hätte dann so gar jedes Fenster eine eigne Farbpalette haben können.

CDXL Videos sind vereinfacht gesagt nichts andres als aufeinander folgende HAM Bilder. Wobei ein CDXL Video nur eine gewissen Anzahl von Bildern haben kann.

Das IFF Format selbst ist ein Container Format, das aus verschieden Blocken besteht. So lassen sich in IFF ILBM auch noch Blöcke hinzufügen. Das haben zum Beispiel manche Grafikprogramme gemacht. So könnte man in einer Grafik auch einen Block mit Kommentaren oder einen Block mit dem Autor einfügen. Diese Blöcke würden dann, zum Beispiel vom MulitView ( universal Anzeige Programm des Amigas ) überlesen und die Grafik dennoch korrekt angezeigt.

Man muss bei einer IFF Datei immer zuerst die ersten Block auslesen. Bei jeder IFF Datei hat man zuerst FORM stehen. Das sind die ersten 4 Byte. In den nächsten 4 Byte steht die gesamt Größe der Datei. Bei einer Grafik steht dann ILBM. Damit wird angegeben das es sich um eine ILBM Grafik handelt. RGB8 würde heißen das es sich im eine 24 Bit Grafik von Turbo Silber handelt. 
Dann kommt BMHD, gefolgt von den Werten der Grafik. Dann Farbkarte und dann der Body. 
Der Witz ist es, es kann auch zuerst die Farbkarte kommen und dann erst BMHD. Die müssen nicht in einer gewissen Reihenfolge stehen. Wichtig ist nur das der Body als letzter steht. Am kann also nicht davon ausgehen das die Block an einer gewissen Adresse stehen. Das heißt man muss die schon suchen in der Datei wo sie sind.  
Aufpassen muss man da auch, weil es immer auch leere Byte gibt. Auch muss man beachten wo genau die Daten eines Blocks stehen. Wenn du meinen Code ansiehst wird du auch sehen das ich die ersten 8 Byte im Body überspringe. Weil ersten 4 Byte BODY stehe. Damit man weiß wo sich der befinden und dann kommen 4 Byte die die Größe des Bodys angeben.

In  Hex Editor sieht das dann so aus. 
FORM�ù(ILBMBMHD��� X������€��,, XBODY�ù�¤nàÃ9�?æ�8|Ľ¡� <¼Ö—ÿçæiÐ

Wie du siehst gibt es hier keine Farbkarte (CMAP Block). Der wird auch bei einer IFF 24 Bit nicht gebraucht. Es gibt aber auch Programme die den Block der Farbkarte bei einer 24 Bit Grafik mit anlegen. Der ist dann leer oder mit ein paar 0 Byte gefühlt.

Ein IFF Format das sicher jeder kennt ist AIFF. TIFF ist vereinfacht gesagt ein aufgeblasenes IFF Format. Wobei Microsoft das so verändert hat das niemand mit Lizenzen kommt.-)

07.09.2024 - 11:23 Uhr

Sorry, hat ein bisschen gedauert, weil ich mir ja eingebildet habe ich muss noch schnell einen Video Konverter machen der auf ffmpeg passiert. Der kann zwar noch  nichts anderes als Videos von einen Format ins andere zu bringen. Aber er lauft super und ist auch schon in WPF gemacht. Und einen Bilder Konverter habe ich mir auch noch eingebildet. Der ist aber noch nicht fertig. Der Dient auch mehr dazu um später mal einen IFF Konverter zu machen. Zuerst mal mit IFF 24Bit, dann auch mal die andern IFF ILBM. Dann halt auch mal HAM6 und HAM8. Zweck des ganzen ist ein Verständnis für die Dateien Formate zu bekommen. Um vielleicht mal in der Lage zu sein auf Windows einen CDXL Konverter zumachen. Bis jetzt gibt es da nur einen guten auf Linux.

Wenn du CDXL nicht kennst kannst du dir das auf meinen Kanal ansehen. Das ist ein CDXL HAM8 auf meinen Amiga 4000, am Amiga 2000 geht das dann nur mit HAM6. Das können alle Amiga ab Werk.  Dazu muss ich aber sagen ich kann Höher FPS und höher Einstellungen in Audio fahren.  Bei Amiga haben einen MC 68060@50. 
Amiga 4000 HAM 8 Video (youtube.com)

Klar kann ein Amiga 24 Bit Grafiken und auch 32 Bit darstellen. (Siehe Bild). So gar als Hintergrundbild. Das kann mein Amiga 2000 und auch Amiga 4000. Setzt aber eine Grafikkarte voraus. Meine Amiga sind auch  Ausgerüstet. Die können auch in Internet. Wobei da kann man halt nur Amiga typisch Seiten anzeigen. Hat aber seine Vorteil wenn sie das können.

Ganz richtig ist das nicht. 64 Farben im Extra Halbrite Modus trifft auf die ersten Amiga zu. Also Amiga 1000, 500, 600, 2000 und 3000. Die Amiga 1200 und Amiga 4000 könnten in dem Modus dann 256 Farben. Wo bei die erste noch dem HAM6 Modus haben mit dem man 4096 Farben anzeigen kann. Der Amiga 1200 und Amiga 4000 können in HAM8 mit dem AGA Chip dann noch mehr anzeigen. 
Tja, und den AAA Chip den hat Commodore leider mit ins Grab genommen. Der hätte schon im Amiga 4000 verbaut sein sollen. Das weiß man weil der Jumper dafür da ist. ( Nur Commodore hat auf Grund des PC Geschafftes zu wenig Geld für die Entwicklung ). Der hätte 16,8 Millionen Farben anzeigen könnten oder bei einer Auflösung von 1260 x 1024 256 Farben. Zumindest wird das immer so gesagt. Der hätte auch sehr schnell sein müssen, weil Commodore damals bekannt gab das man mit den Chip ein Fenster in dem ein Video läuft verschieben kann und das Video dabei weiter läuft.

Erzeugt habe ich übrigens die IFF 24 Bit Grafiken am Amiga mit dem Picture Manager 5.5. Am könnte sie zwar auch mit XnView auf dem PC erzeugen. Nur baut das immer dann eine Maske mit ein. Was das ganze noch schwerer macht.

Auf diesen Gedankengang bin ich durch diesen Betrag von mir in Amiga Englisch Board gekommen.

IFF 24 Bit richtig gelesen? - Englisches Amiga-Board (abime.net)

So wie ich das Verstehe sind die Daten dort so gespeichert wie ich das Beschrieben habe.

Aber ich kann das ja mal versuchen das so auszulesen wie du das beschreibst. 
Ganz kapiere ich es aber noch nicht. Also da heißt bei einer Grafik von 800 x 600 würden zuerst 800 Byte für Rot kommen, dann 800 Byte für Grün und dann 800 für Blau.

PS: Egal wie viele versuche daneben gehen, ich lerne so immer was neues über C# dabei.

07.09.2024 - 07:49 Uhr

Zitat von Gerwald

Ne da habe ich wohl falsch geklickt, man sollte halt keine Beträge schreiben vor dem Ersten Kaffee. Könnte aber auch sein das der Beitrag zu lange ist. 
Ich teile in daher auf mehrere auf.

@Th69:

Eine IFF Datei, egal ob sie Text, Sound, Amin oder Grafik (ILBM) enthält teilt sich immer in mehre Blöcke auf. Bild Breite und Höhe stehen dann im BMHD Block.
Der ist so aufgebaut.

BMHD-Blockstruktur laut Dokumentation: 
Blocktyp (BMHD)                              bmhdIndex Byte 0-4
Unbenutzt (2 Bytes)                         bmhdIndex Byte 5-7
Bildbreite (2 Bytes)                           bmhdIndex Byte 8-9
Bildhöhe (2 Bytes)                             bmhdIndex Byte 10-11
X-Versatz (2 Bytes)                           bmhdIndex Byte 12-13
Y-Versatz (2 Bytes)                           bmhdIndex Byte 14-15
Anzahl der Bitplanes (1 Byte)           bmhdIndex Byte 16
Maskierungstechnik (1 Byte)            bmhdIndex Byte 17
Komprimierungstechnik (1 Byte)      bmhdIndex Byte 18
Padbyte (1 Byte, ungenutzt              bmhdIndex Byte 19
Transparentfarbe (2 Bytes)              bmhdIndex Byte 20-21
X-Aspektverhältnis (1 Byte)              bmhdIndex Byte 22
Y-Aspektverhältnis (1 Byte)              bmhdIndex Byte 23
Bildschirmbreite (2 Bytes)                bmhdIndex Byte 24-25
Bildschirmhöhe (2 Bytes)                  bmhdIndex Byte 26-27

Der wird von meinen Code auch korrekt ausgelesen.  Hier muss man nur aufpassen wegen höherwertigen und niederwertigen Byte. Da macht der Amiga anders als ein PC.

Die Grafikdaten stehen dann im Block Body. Wobei die ersten 8 Byte übersprungen werden müssen. In den ersten 4 Byte steht, BODY und in den nächsten 4 Byte ist die Größe des Body gespeichert. Aber nur die Größe es Body nicht die gesamt Größe der Datei, die ist an einer anderen Stelle gespeichert.

07.09.2024 - 07:47 Uhr

Das ist jetzt der Code mit dem ich das Auslese.

Die Debug.WriteLine Befehle habe ich nur dazu eingefügt damit ich sehe, ob die Schleifen richtig laufen und richtig gezählt wird.

  // ********** IFF ILBM in Bitmap erstellen **********
 private void bitmap_Erstellen(System.Object sender, EventArgs e)
 {
     if (intMaske != 0 || kompresion != 0)
     {
         MessageBox.Show("Zur Zeit konnen nur Bilder ohne Maske und Kompresion angezeigt werden!");
         return;
     }
     // Bitmap erstellen
     Bitmap flag = new Bitmap(bildBreite, bildHoehe, PixelFormat.Format24bppRgb);
     using (FileStream fs = new FileStream(fileIFF, FileMode.Open, FileAccess.Read))
     {
         BinaryReader br = new BinaryReader(fs);
         // Zu Bodydaten springen
         br.BaseStream.Seek(bodyIndex + 8, SeekOrigin.Begin);
         int byteBody = (bildBreite * bildHoehe * 3);
         byte[] bodyData = br.ReadBytes(byteBody);
         // Überprüfen, ob bodyData korrekt gelesen wurde
         if (bodyData == null || bodyData.Length == 0)
         {
             MessageBox.Show("Body-Daten konnten nicht gelesen werden.");
             return;
         }
         // Sprung Adresse errechnen.
         hauptzaehler = ((bildBreite * bildHoehe * 3) / 24);   // Hauptzähler berechnen
         bytezaehler = (bildBreite * bildHoehe) / 8;         // Einsprung berechnen für Farbwerte
         rotByteArray = 0;                                   // Einsprung Adresse die Farbe Rot in IFF Body
         gruenByteArray = bildBreite * bildHoehe;            // Einsprung Adresse die Farbe Grüne in IFF Body
         blauByteArray = (bildBreite * bildHoehe) * 2;       // Einsprung Adresse die Farbe Blau in IFF Body
         // Zähler zum zuweisen der Farben in Bitmap auf Null setzen
         bitmapZaehlerBreite = 0;
         bitmapZaehlerHoehe = 0;
         hz = 0;         // Zähler für hauptzähler auf Null setzen
         byte[] RotByte = new byte[8];
         byte[] GruenByte = new byte[8];
         byte[] BlauByte = new byte[8];
         Debug.WriteLine($"Breite: {bildBreite}");
         Debug.WriteLine($"Höhe: {bildHoehe}");
         Debug.WriteLine($"Hauptzähler: {hauptzaehler}");
         Debug.WriteLine($"\nrotByteIndex: {rotByteIndex}");
         Debug.WriteLine($"gruenByteIndex: {gruenByteIndex}");
         Debug.WriteLine($"blauByteIndex: {blauByteIndex}");
         Debug.WriteLine($"bytezaehler: {bytezaehler}\n");
         while (hz < hauptzaehler)
         {
             rotByteIndex = rotByteArray;
             gruenByteIndex = gruenByteArray;
             blauByteIndex = blauByteArray;
             rotByteIndex += hz;
             gruenByteIndex += hz;
             blauByteIndex += hz;        
                 // Arrays zurücksetzen
                 Array.Clear(RotByte, 0, RotByte.Length);
             Array.Clear(GruenByte, 0, GruenByte.Length);
             Array.Clear(BlauByte, 0, BlauByte.Length);
             // Rot auslesen für 8 Pixel
             for (int pixelPosRot = 0; pixelPosRot < 8; pixelPosRot++)
             {
                 Debug.WriteLine($"pixelPosRot: {pixelPosRot}, rotByteIndex: {rotByteIndex}");
                 pixelRGB[pixelPosRot] = bodyData[rotByteIndex];
                 rotByteIndex += bytezaehler;
             }
             Debug.WriteLine($"\n");
             // Grün auslesen für 8 Pixel
             for (int pixelPosGruen = 8; pixelPosGruen < 16; pixelPosGruen++)
             {
                 Debug.WriteLine($"pixelPosGruen: {pixelPosGruen}, grünByteIndex: {gruenByteIndex}");
                 pixelRGB[pixelPosGruen] = bodyData[gruenByteIndex];
                 gruenByteIndex += bytezaehler;
                
             }
             Debug.WriteLine($"\n");
             // Blau auslesn für 8 Pixel
             for (int pixelPosBlau = 16; pixelPosBlau < 24; pixelPosBlau++)
             {
                 Debug.WriteLine($"pixelPosBlau: {pixelPosBlau}, blauByteIndex: {blauByteIndex}");
                 pixelRGB[pixelPosBlau] = bodyData[blauByteIndex];
                 blauByteIndex += bytezaehler;
             }
             Debug.WriteLine($"\n");
             // pixelRGB den Byte in der Bitmap zu ornden. 
             for (int i = 0; i < 8; i++)
              {
                  for (int bit = 0; bit < 8; bit++)
                  {
                      // RotByte
                      RotByte[bit] |= (byte)((pixelRGB[i] & (1 << (7 - bit))) != 0 ? (1 << (7 - i)) : 0);
                      // GruenByte
                      GruenByte[bit] |= (byte)((pixelRGB[i + 8] & (1 << (7 - bit))) != 0 ? (1 << (7 - i)) : 0);
                      // BlauByte
                      BlauByte[bit] |= (byte)((pixelRGB[i + 16] & (1 << (7 - bit))) != 0 ? (1 << (7 - i)) : 0);
                  }
              }
             hz += 1;
             Debug.WriteLine($"\nHz: {hz}");
             // Farben der Bitmap zuweisen
             for (int z = 0; z < 8; z++)
              {
                  Debug.WriteLine($"RotByte:  {RotByte[z]} GrünByte: {GruenByte[z]} BlauByte: {BlauByte[z]}");
                  flag.SetPixel(bitmapZaehlerBreite, bitmapZaehlerHoehe, Color.FromArgb(RotByte[z], GruenByte[z], BlauByte[z]));
                  Debug.WriteLine($"\nBreite: {bitmapZaehlerBreite}");
                  Debug.WriteLine($"Hohe: {bitmapZaehlerHoehe}");
                  if (bitmapZaehlerBreite < bildBreite -1)
                  {
                      bitmapZaehlerBreite += 1;
                  }
                  else
                  {
                      bitmapZaehlerBreite = 0;
                      bitmapZaehlerHoehe++;
                  }
              }
         }
07.09.2024 - 07:45 Uhr

Ich muss leider Sagen das mein Ansatz den Body auszulesen falsch war.

Die Dokumentation dazu ist leider auch nicht die beste. Ich habe das zuerst so verstanden das im Body die Daten als RGB gespeichert sind. Also so wie auf einen PC. Das ist mir zwar auch komisch vorgekommen, weil ein Amiga Grafik nicht so speichert, aber man kann es halt so verstehen wie es beschreiben ist. 
Dazu muss man halt sagen das man eine IFF 24 Bit halt nicht so einfach vergleichen kann. Den in der gibt es keine Farbkarte mehr wie das sonst der Fall ist. 
Die Farbkarte würde man im CAMP Block finden. Der ist aber bei einer 24 Bit Grafik leer, weil er ganz einfach zu groß wäre.

Daher stehen die Farben direkt im BODY Block. Allerdings sind sie dann auch bei einer 24 BIT IFF gedreht wie ein Amiga das so macht, ( Das hat auch Apple mal so gemacht ).  Wenn man sich die Ebenen der Grafik drei Dimensional vorstellt ist die dann um 90 Grad gedreht.

Sie stehen also so im Speicher. 
Byte 0           Byte 1           Byte 2    ...

R0  01234567   01234567   01234567

R1  01234567   01234567   01234567

R2  01234567   01234567   01234567

R3  01234567   01234567   01234567

und so weiter.

Das heißt in der ersten Ebene stehen für alle Pixel der Wert von R0. Also das erste Bit für Rot. In der zweiten Ebene das zweite Bit für Rot und so weiter. Dann kommen die Werte für Grün und dann für Blau.

Wen meine Gedankengänge stimmen würde das heißen.

Bei einer Grafik von 800 x 600 Pixel, wäre die Grafik Daten im Body 1 440 000 Byte groß. ( Nur die Grafikdaten, die ganze Datei hätte dann 1 440 040 Byte)

Das müsste heißen die Blöcke für Rot, Grün und Blau sind immer 480 000 Byte groß. Jede Ebene wäre dann 60 000 Byte groß. 
Für das erste Pixel müsste dann das erste Bit im Byte 0 stehen. Das zweit Bit dann im Byte an der Stelle 60 000, das dritte Bit für Rot an der stelle 120 000 und so weiter. 
Die Werte für Grün sollten dann beim Byte an der Stelle 480 000 beginnen und für Blau bei 960 000.

Das heißt ich muss für die Farbe für ein Pixel 24 Byte auslesen. gebraucht wird aber für ein Pixel immer nur ein 1 Bit aus den 24 Byte. Weil man damit aber schon die Farbwerte von 8 Pixel liest. Habe ich das so gemacht das die einzelne Bit gleich 8 Pixel zu gewissen werden.

Nur leider bekomme ich halt nur Datenmüll. Komischerweise hat dieser Datenmüll viele  Grün. Die Grafik besteht aber mehr aus Rot und Orange. 
Also könnte es sein das meine Zuordnung der Bit falsch ist, oder meine Gedankengänge.

07.09.2024 - 07:15 Uhr

Ne da habe ich wohl falsch geklickt, man sollte halt keine Beträge schreiben vor dem Ersten Kaffee. Könnte aber auch sein das der Beitrag zu lange ist. 
Ich teile in daher auf mehrere auf.

@Th69:

Eine IFF Datei, egal ob sie Text, Sound, Amin oder Grafik (ILBM) enthält teilt sich immer in meiner Blöcke auf. Bild Breite und Höhe stehen dann im BMHD Block.
Der ist so aufgebaut.

BMHD-Blockstruktur laut Dokumentation: 
Blocktyp (BMHD)                              bmhdIndex Byte 0-4
Unbenutzt (2 Bytes)                         bmhdIndex Byte 5-7
Bildbreite (2 Bytes)                           bmhdIndex Byte 8-9
Bildhöhe (2 Bytes)                             bmhdIndex Byte 10-11
X-Versatz (2 Bytes)                           bmhdIndex Byte 12-13
Y-Versatz (2 Bytes)                           bmhdIndex Byte 14-15
Anzahl der Bitplanes (1 Byte)           bmhdIndex Byte 16
Maskierungstechnik (1 Byte)            bmhdIndex Byte 17
Komprimierungstechnik (1 Byte)      bmhdIndex Byte 18
Padbyte (1 Byte, ungenutzt              bmhdIndex Byte 19
Transparentfarbe (2 Bytes)              bmhdIndex Byte 20-21
X-Aspektverhältnis (1 Byte)              bmhdIndex Byte 22
Y-Aspektverhältnis (1 Byte)              bmhdIndex Byte 23
Bildschirmbreite (2 Bytes)                bmhdIndex Byte 24-25
Bildschirmhöhe (2 Bytes)                  bmhdIndex Byte 26-27

Der wird von meinen Code auch korrekt ausgelesen.  Hier muss man nur aufpassen wegen höherwertigen und niederwertigen Byte. Da macht der Amiga anders als ein PC.

Die Grafikdaten stehen dann im Block Body. Wobei die ersten 8 Byte übersprungen werden müssen. In den ersten 4 Byte steht, BODY und in den nächsten 4 Byte ist die Größe des Body gespeichert. Aber nur die Größe es Body nicht die gesamt Größe der Datei, die ist an einer anderen Stelle gespeichert.

07.09.2024 - 07:02 Uhr

Uff ich sehe meine neuen Beitrag jetzt nicht. Ich hoffe ich habe da nix falsch angeklickt, sonst kann ich ihn noch mal schreiben. Oder muss der zuerst freigeschalten werden. Muss ich halt mal warten, wenn da nichts kommt muss ich es noch mal schreiben.

Aber ich hänge mal ein Bild an wie das dann aussieht.

03.08.2024 - 19:52 Uhr

Ich habe angefangen mit dem Programmieren angefangen.

Jetzt versuche ich gerade ein Programm zu machen das IFF ILBM 24 Bit anzeigen kann. Diese Bilder haben keinen Maske und keine Komprision. Die werden auch auf einen Amiga kortekt angezeigt.

Ich lese den Body der IFF Datei wird auch korrekt gelesen und übertrage die Daten in eine Bitmap. 
Nur bei meinen Programm bekomme ich nur Datenmüll angezeigt.

Ein Möglichkeit wäre das die Daten nicht richtig in die Bitmap eingetragen werden. Mein Frage daher wie ist die Bitmap genau in C# aufgebaut?

So sieht der Code aus, der den Body ausliest. Vielleicht habe ich ja als Anfänger auch da einen Denkfehler

 private void bitmap_Erstellen(System.Object sender, EventArgs e)
{
    if (intMaske != 0 || kompresion != 0)
    {
        MessageBox.Show("Zur Zeit konnen nur Bilder ohne Maske und Kompresion angezeigt werden!");
        return;
    }
    Bitmap flag = null;
    // Bitmap erstellen
    flag = new Bitmap(bildBreite, bildHoehe, PixelFormat.Format24bppRgb);
    using (FileStream fs = new FileStream(fileIFF, FileMode.Open, FileAccess.Read))
    {
        BinaryReader br = new BinaryReader(fs);
        // Zu Bodydaten springen
        br.BaseStream.Seek(bodyIndex + 8, SeekOrigin.Begin);
        int byteBody = (bildBreite * bildHoehe * 3);
        byte[] bodyData = br.ReadBytes(byteBody);
        int bodyDataSize = bodyData.Length;        
        // Überprüfen, ob bodyData korrekt gelesen wurde
        if (bodyData == null || bodyData.Length == 0)
        {
            MessageBox.Show("Body-Daten konnten nicht gelesen werden.");
            return;
        }
        /*
        // Die ersten 8 Werte anzeigen
        Debug.WriteLine("Erste 8 Werte:");
        for (int i = 0; i < 8 && i < bodyData.Length; i++)
        {
            Debug.WriteLine($"Wert {i + 1}: {bodyData[i]} (Hex: {bodyData[i]:X2})");
        }
        */
        for (indexhoehe = 0; indexhoehe < bildHoehe; indexhoehe++)
        {
            for (indexbreite = 0; indexbreite < bildBreite; indexbreite++)
            {
                pixelIndex = (indexhoehe * bildBreite + indexbreite) * 3;
                byte byteRot = bodyData[pixelIndex];
                byte byteGruen = bodyData[pixelIndex + 1];
                byte byteBlau = bodyData[pixelIndex + 2];
                //byte byteAlpha = bodyData[pixelIndex + 3];
                // Byte-Werte anzeigen
                //Debug.WriteLine($"Pixel ({indexbreite}, {indexhoehe}): Rot = {byteRot} (Hex: {byteRot:X2}), Grün = {byteGruen} (Hex: {byteGruen:X2}), Blau = {byteBlau} (Hex: {byteBlau:X2})");
                //
                // Setze die Pixel in der Bitmap
                Color color = Color.FromArgb(byteRot, byteGruen, byteBlau);
                flag.SetPixel(indexbreite, indexhoehe, color);
                int width = flag.Width;
                int height = flag.Height;
                int pixelSize = 3;
                int flagSize = width * height * pixelSize;
                label1.Text = ("Größe Body " + bodyDataSize.ToString() + " Größe Flag: " + flagSize);
            }
        }
    }
    pictureBox1.Image = flag; // In einer PictureBox anzeigen
}