[Hilfestellung]Erstellen eines BMP-Files (richtiger Header) aus unsigned char.



  • Hallo,

    ich habe ein unsigned char array der Dimension 744 x 480 monochrom 8 bit. Dieses möchte ich ohne Verwendung einer zusätlichen Bibliothek in einem .bmp-File speichern. Ich habe schon nach dem Wiki http://en.wikipedia.org/wiki/BMP_file_format#Example_1 ein Grundgerüst erstellt:

    void BMP_WriteBitmap(unsigned char* PictureBuffer, char* FileName)
    {	
    	FILE* fBmpFile = fopen(FileName, "wb");
    
    	if (fBmpFile == NULL)
    	{
    		printf("Error:\tUnable to save file %s.bmp.\n", FileName);
    		exit(0);
    	}
    	else
    	{
    		unsigned int bitmapCompleteSize = 744 * 480 + 54;
    		unsigned int bCsLo = bitmapCompleteSize % 65536;
    		unsigned int bCsHi = bitmapCompleteSize / 65536;
    		unsigned int bitmapDataSize = 744 * 480;
    		unsigned int bDsLo = bitmapCompleteSize % 65536;
    		unsigned int bDsHi = bitmapCompleteSize / 65536;
    /**************************************************************************/
    /*	BMP-Header	*/
    		unsigned char bitmapType[2] = "\x42\x4D";
    		unsigned char bitmapSize[4];   // Größe des gesamten Bildes + Header in 4 Byte
    		bitmapSize[0] = bCsLo % 256;
    		bitmapSize[1] = bCsLo / 256;
    		bitmapSize[2] = bCsHi % 256;
    		bitmapSize[3] = bCsHi / 256;
    		unsigned char Reserved[4] = "\x00\x00\x00\x00";
    		unsigned char bitmapOffset[4] = "\x36\x00\x00\x00";    // Offset = 54Byte
    		fwrite(&bitmapType, sizeof(unsigned char), 2, fBmpFile);
    		fwrite(&bitmapSize, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&Reserved, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapOffset, sizeof(unsigned char), 4, fBmpFile);
    /**************************************************************************/
    /*	BMP-Information	*/
    		unsigned char bitmapInfoSize[4] = "\x28\x00\x00\x00";
    		unsigned char bitmapWidth[4];    // Weite des Bildes in 4 Byte
    		bitmapWidth[0] = 744 % 256;
    		bitmapWidth[1] = 744 / 256;
    		bitmapWidth[2] = '\x00';
    		bitmapWidth[3] = '\x00';
    		unsigned char bitmapHeight[4];    // Höhe des Bildes in 4 Byte
    		bitmapHeight[0] = 480 % 256;
    		bitmapHeight[1] = 480 / 256;
    		bitmapHeight[2] = '\x00';
    		bitmapHeight[3] = '\x00';
    		unsigned char bitmapBiPlanes[2] = "\x01\x00";
    		unsigned char bitmapBiBitCount[2] = "\x08\x00";    // hier 8 für monochrom
    		unsigned char bitmapBiCompression[4] = "\x00\x00\x00\x00";
    		unsigned char bitmapBiSizeImage[4];    // Größe des Bildes ohne Header
    		bitmapBiSizeImage[0] = bDsLo % 256;
    		bitmapBiSizeImage[1] = bDsLo / 256;
    		bitmapBiSizeImage[2] = bDsHi % 256;
    		bitmapBiSizeImage[3] = bDsHi / 256;
    		unsigned char bitmapBiXPPM[4] = "\x13\x0B\x00\x00";
    		unsigned char bitmapBiYPPM[4] = "\x13\x0B\x00\x00";
    		unsigned char bitmapBiClrUsed[4] = "\x00\x00\x00\x00";
    		unsigned char bitmapBiClrImportant[4] = "\x00\x00\x00\x00";
    		fwrite(&bitmapInfoSize, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapWidth, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapHeight, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiPlanes, sizeof(unsigned char), 2, fBmpFile);
    		fwrite(&bitmapBiBitCount, sizeof(unsigned char), 2, fBmpFile);
    		fwrite(&bitmapBiCompression, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiSizeImage, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiXPPM, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiYPPM, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiClrUsed, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiClrImportant, sizeof(unsigned char), 4, fBmpFile);
    /**************************************************************************/
    /*	Data	*/
    		fwrite(PictureBuffer, sizeof(unsigned char),bitmapDataSize , fBmpFile);
    		fclose(fBmpFile);
    	}
    }
    

    Leider scheine ich bei dem Header noch Probleme zu haben, diesen richtig zu erstellen. Da ich schlussendlich kein Bild in der .bmp-File sehen kann. Sieht jemand vieleicht bei der Übergabe von Bildgröße, Bildformat(monochrom), Bildweite und Bildhöhe (bei diesen Werten vermute ich meinen Fehler) etwas falsches?

    Vielen dank
    mirrowwinger



  • Du solltest mittlerweile wissen, das der Adressoperator bei Arrays überflüssig ist.
    Falls du mal ein Array durch dynamischen Speicher ersetzt auch falsch.
    Bei

    unsigned char bitmapType[2] = "\x42\x4D"; 
    //oder
    unsigned char Reserved[4] = "\x00\x00\x00\x00";
    

    bekommt man Augencrepes

    unsigned char bitmapType[2] = {'B', 'M'}; //oder auch "BM"
    //oder
    unsigned char Reserved[4] = {0}; // der Rest wird mit 0 aufgefüllt.
    

    Du musst deine Bitmmap mal in einem Hexviewer/-editor ansehen. Die Ausgabe kannst du dann mit der Wikiseite vergleichen.



  • Also hab erstmal Bitmaps analysiert. Dazu habe ich mit Hilfe von openCV bmp-Dateien gespeichert. Nach der Analyse habe ich folgende Funktion erzeugt, die ein funktionstüchtiges BMP-File erzeugt. Hierzu habe ich aber noch eine Frage zu einem bestimmten Bereich. Ich bitte auch gleich DirkB und alle die meinen ersten Quellcode als Augencrepes bezeichnen um Entschuldigung wenn auch der 2. Quellcode diesem Prinzip enspricht aber es ist schön leicht die Informationen aus dem Hex-Editor so in eine Funktion umzusetzen. Wem es beliebt darf es ja anders machen 😋 .

    void BMP_WriteBitmap(unsigned char* PictureBuffer, char* FileName)
    {	
    	FILE* fBmpFile = fopen(FileName, "wb");
    
    	if (fBmpFile == NULL)
    	{
    		printf("Error:\tUnable to save file %s.bmp.\n", FileName);
    		exit(0);
    	}
    	else
    	{
    		unsigned int bitmapCompleteSize = WIDTH * HEIGHT + 1060;
    		unsigned int bCsLo = bitmapCompleteSize % 65536;
    		unsigned int bCsHi = bitmapCompleteSize / 65536;
    		unsigned int bitmapDataSize = WIDTH * HEIGHT;
    		unsigned int bDsLo = bitmapCompleteSize % 65536;
    		unsigned int bDsHi = bitmapCompleteSize / 65536;
    /**************************************************************************/
    /*	BMP-Header	*/
    		unsigned char bitmapType[2] = "\x42\x4D";
    		//unsigned char bitmapSize[4] = "\x76\x00\x00\x00";
    		unsigned char bitmapSize[4];
    		bitmapSize[0] = bCsLo % 256;
    		bitmapSize[1] = bCsLo / 256;
    		bitmapSize[2] = bCsHi % 256;
    		bitmapSize[3] = bCsHi / 256;
    		unsigned char Reserved[4] = "\x00\x00\x00\x00";
    		unsigned char bitmapOffset[4] = "\x36\x04\x00\x00";
    		fwrite(&bitmapType, sizeof(unsigned char), 2, fBmpFile);
    		fwrite(&bitmapSize, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&Reserved, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapOffset, sizeof(unsigned char), 4, fBmpFile);
    /**************************************************************************/
    /*	BMP-Information	*/
    		unsigned char bitmapInfoSize[4] = "\x28\x00\x00\x00";
    		unsigned char bitmapWidth[4];
    		bitmapWidth[0] = WIDTH % 256;
    		bitmapWidth[1] = WIDTH / 256;
    		bitmapWidth[2] = '\x00';
    		bitmapWidth[3] = '\x00';
    		unsigned char bitmapHeight[4];
    		bitmapHeight[0] = HEIGHT % 256;
    		bitmapHeight[1] = HEIGHT / 256;
    		bitmapHeight[2] = '\x00';
    		bitmapHeight[3] = '\x00';
    		unsigned char bitmapBiPlanes[2] = "\x01\x00";
    		unsigned char bitmapBiBitCount[2] = "\x08\x00";
    		unsigned char bitmapBiCompression[4] = "\x00\x00\x00\x00";
    		unsigned char bitmapBiSizeImage[4] = "\x00\x00\x00\x00";
    		unsigned char bitmapBiXPPM[4] = "\x00\x00\x00\x00";
    		unsigned char bitmapBiYPPM[4] = "\x00\x00\x00\x00";
    		unsigned char bitmapBiClrUsed[4] = "\x00\x00\x00\x00";
    		unsigned char bitmapBiClrImportant[4] = "\x00\x00\x00\x00";
    		fwrite(&bitmapInfoSize, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapWidth, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapHeight, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiPlanes, sizeof(unsigned char), 2, fBmpFile);
    		fwrite(&bitmapBiBitCount, sizeof(unsigned char), 2, fBmpFile);
    		fwrite(&bitmapBiCompression, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiSizeImage, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiXPPM, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiYPPM, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiClrUsed, sizeof(unsigned char), 4, fBmpFile);
    		fwrite(&bitmapBiClrImportant, sizeof(unsigned char), 4, fBmpFile);
    /**************************************************************************/
    /*	unknown data	*/
    		int i;
    		for (i = 0; i <= 255; i++)
    		{
    			unsigned char unknown[4] = {(char)i, (char)i, (char)i, '\x00'};
    			fwrite(&unknown, sizeof(unsigned char), 4, fBmpFile);
    		}
    /**************************************************************************/
    /*	Data	*/
    		fwrite(PictureBuffer, sizeof(unsigned char), bitmapDataSize, fBmpFile);
    		fclose(fBmpFile);
    	}
    }
    

    Wie man sieht hat sich etwas am Header geändert vor allem ist er durch den Block, welchen ich mit unknown Data bezeichnet habe vergrößert worden. Hier wäre meine Frage, wenn denn jemand sich damit auskennt, was sind das für Daten? Nochmals als Hinweis OPENCV hat das Vorlage-Bitmap erstellt. Kann natürlich sein, dass es unsinnige Daten sind, könnte aber vieleicht auch sowas wie eine Farbpalette(?) sein?

    Im Hex-Editor sieht der unknown-data-Block wie folgt aus:

    00 00 00 00 01 01 01 00 02 02 02 00 03 03 03 00 04 04
    04 00 05 05 05 00 06 06 06 00 07 07 07 00 08 08 08 00
    ...
    

    Ich denke das System dahinter wird durch die 2 Zeilen klar. Wie gesagt wäre gut, ween jemand sagen könnte, was diese Daten bedeuten im Header oder ob sie überflüssig sind.

    MfG
    mirrowwinger



  • Ja, dies ist die "Color table" (siehe entsprechenden Eintrag in der Wiki) und diese sind als semi-optional eingestuft (d.h. es ist besser sie hinzuzufügen als wegzulassen), aber bei BPP <= 8 zwingend erforderlich!
    Aber je nach Bitmap-Header Version können vorher auch noch "channel bitmasks" und "color space types" kommen (s. Diagramm " The structure of the bitmap image file" in der Wiki).



  • Verwende besser ein Array ausreichender Größe, befülle es entsprechend und benutze genau 1x fwrite. Ist dann auch einfacher im Debugger nachzuverfolgen.



  • Hallo nochmal,

    habe mich nach ein paar Wochen seit dem letzten Post wirklich ran gemacht und eine Funktion mit einem Array und einer fwrite-Anweisung nutzt und möchte gern mal eure Manöverkritik dazu hören.

    void BMP_WriteBitmap(unsigned char* PictureBuffer, char* FileName)
    {	
    	FILE* fBmpFile = fopen(FileName, "wb");
    
    	if (fBmpFile == NULL)
    	{
    		printf("Error:\tUnable to save file %s.bmp.\n", FileName);
    		exit(0);
    	}
    	else
    	{
    		unsigned int bitmapCompleteSize = WIDTH * HEIGHT + 1078;
    		unsigned char uc_BitmapFile[bitmapCompleteSize];
    		unsigned int bCsLo = bitmapCompleteSize % 65536;
    		unsigned int bCsHi = bitmapCompleteSize / 65536;
    		unsigned int bitmapDataSize = WIDTH * HEIGHT;
    /**************************************************************************/
    /*	BMP-Header	*/
    		uc_BitmapFile[0] = '\x42';
    		uc_BitmapFile[1] = '\x4D';
    		uc_BitmapFile[2] = bCsLo % 256;
    		uc_BitmapFile[3] = bCsLo / 256;
    		uc_BitmapFile[4] = bCsHi % 256;
    		uc_BitmapFile[5] = bCsHi / 256;
    		uc_BitmapFile[6] = '\x00';
    		uc_BitmapFile[7] = '\x00';
    		uc_BitmapFile[8] = '\x00';
    		uc_BitmapFile[9] = '\x00';
    		uc_BitmapFile[10] = '\x36';
    		uc_BitmapFile[11] = '\x04';
    		uc_BitmapFile[12] = '\x00';
    		uc_BitmapFile[13] = '\x00';
    /**************************************************************************/
    /*	BMP-Information	*/
    		uc_BitmapFile[14] = '\x28';
    		uc_BitmapFile[15] = '\x00';
    		uc_BitmapFile[16] = '\x00';
    		uc_BitmapFile[17] = '\x00';
    		uc_BitmapFile[18] = WIDTH % 256;
    		uc_BitmapFile[19] = WIDTH / 256;
    		uc_BitmapFile[20] = '\x00';
    		uc_BitmapFile[21] = '\x00';
    		uc_BitmapFile[22] = HEIGHT % 256;
    		uc_BitmapFile[23] = HEIGHT / 256;
    		uc_BitmapFile[24] = '\x00';
    		uc_BitmapFile[25] = '\x00';
    		uc_BitmapFile[26] = '\x01';
    		uc_BitmapFile[27] = '\x00';
    		uc_BitmapFile[28] = '\x08';
    		uc_BitmapFile[29] = '\x00';
    		uc_BitmapFile[30] = '\x00';
    		uc_BitmapFile[31] = '\x00';
    		uc_BitmapFile[32] = '\x00';
    		uc_BitmapFile[33] = '\x00';
    		uc_BitmapFile[34] = '\x00';
    		uc_BitmapFile[35] = '\x00';
    		uc_BitmapFile[36] = '\x00';
    		uc_BitmapFile[37] = '\x00';
    		uc_BitmapFile[38] = '\x00';
    		uc_BitmapFile[39] = '\x00';
    		uc_BitmapFile[40] = '\x00';
    		uc_BitmapFile[41] = '\x00';
    		uc_BitmapFile[42] = '\x00';
    		uc_BitmapFile[43] = '\x00';
    		uc_BitmapFile[44] = '\x00';
    		uc_BitmapFile[45] = '\x00';
    		uc_BitmapFile[46] = '\x00';
    		uc_BitmapFile[47] = '\x00';
    		uc_BitmapFile[48] = '\x00';
    		uc_BitmapFile[49] = '\x00';
    		uc_BitmapFile[50] = '\x00';
    		uc_BitmapFile[51] = '\x00';
    		uc_BitmapFile[52] = '\x00';
    		uc_BitmapFile[53] = '\x00';
    /**************************************************************************/
    /*	colormap	*/
    		int i;
    		for (i = 0; i <= 255; i++)
    		{
    			uc_BitmapFile[54 + 4 * i] = (char)i;
    			uc_BitmapFile[55 + 4 * i] = (char)i;
    			uc_BitmapFile[56 + 4 * i] = (char)i;
    			uc_BitmapFile[57 + 4 * i] = '\x00';
    		}
    /**************************************************************************/
    /*	Data	*/
    		memcpy(&uc_BitmapFile[1078], PictureBuffer, bitmapDataSize);
    		fwrite(uc_BitmapFile, sizeof(unsigned char), bitmapCompleteSize, fBmpFile);
    		fclose(fBmpFile);
    	}
    }
    


  • 1. BITTE schau dir endlich structs in c an.
    dateistructukturen und dateiformate legt man immer in structs an.
    man kann es zwar theoretisch so machen wie du, aber das ist unübersichtllich und außerdem schlechter stil (also nichts gegen dich - als anfänger kann man das nicht wissen).

    2. du solltest di rückgabewerte von fread überprüfen. nur so kannst du festestellen, ob daten korrekt in die datei geschrieben wurden.
    möglicherweise liegt hier ein solcher fall vor.

    3. warum wird bei dir die weite (width) und die höhe (height) des bildes als array gespeichert?

    4. eine bmp-datei enthält nicht nur einen header, sondern auch eine info-struktur. du hast hier alles auf 0 gesetzt. leider kann man anhand des arraynamen (z.b. "uc_BitmapFile[39]") nicht erkennen, welches element einer bmp-datei du gerade in die datei schreibst.

    5. generell: array nur dann nutzen, wenn es sinn macht (z.b. bei die pixeldaten kann man als array speichern), sonst bitte die dateitypen in c benutzen.



  • Hmm warum beklagst du dich wegen dem einen Array? Wenn aufmerksam meinen letzten und den Beitrag davor gelesen hättest, dann wüsstest du, dass dieser mich quasi direkt aufgevordert hat NUR EIN Array und EIN Write zu nutzen. Da dies einer der wenigen Beiträge zu meiner Frage war, bin ich diesem nachgegangen. Wenn du einen besseren Tip hast, bin ich dir dafür dankbar. Was für Infos du meinst, kann ich mir vorstellen, habe mir ja das entsprechende Wiki angesehen und anschließend ein in OpenCV gespeichertes Bild genommen und danach dieses char-Array entwickelt. Warum ich z.B. Weite und Höhe in der Art speichere wird auch aus den Wikis/ einem Beispielbild klar. Ein Struct hilft mir ebenfalls nicht weiter, weil ich am Ende diesen String genau so in eine Datei schreiben muss (es funktioniert ja auch)! Das Struct bläht meinen Code nur aus und hat keinen weiteren Nutzen. (Du darfst mich natürlich gern korrigieren)



  • Statt

    uc_BitmapFile[0] = '\x42';
            uc_BitmapFile[1] = '\x42';
            uc_BitmapFile[2] = '\x42';
            uc_BitmapFile[3] = bCsLo / 256;
            uc_BitmapFile[4] = bCsHi % 256;
            uc_BitmapFile[5] = bCsHi / 256;
            uc_BitmapFile[6] = '\x00';
            uc_BitmapFile[7] = '\x00';
            uc_BitmapFile[8] = '\x00';
            uc_BitmapFile[9] = '\x00';
            uc_BitmapFile[10] = '\x36';
            uc_BitmapFile[11] = '\x04';
            uc_BitmapFile[12] = '\x00';
            uc_BitmapFile[13] = '\x00';
    

    schreibt man üblicherweise bei der Initialisierung lieber

    char uc[14]={0x42,0x42,0x42,bCsLo/256,bCsHi%256,bCsHi/256,0x00,
                 0x00,0x00,0x00,     0x36,     0x04,     0x00,0x00
                };
    

    Das ist kürzer und übersichtlicher, oder manchmal auch ohne endende 0, also

    char uc[14]={0x42,0x42,0x42,bCsLo/256,bCsHi%256,bCsHi/256,0x00,
                 0x00,0x00,0x00,     0x36,     0x04
                };
    

    Die Dimension sollte man (außer evtl. bei Stringliteralinitialisierungen) immer mit angeben, manche Compiler warnen, wenn man sich mal verzählt, also

    int i[4]={0,1,3,4,5};
    

    wäre so ein Kandidat, der Compiler kann besser zählen als man selbst und vor allen Dingen, ein Compiler verrechnet sich nicht.

    Zum anderen Thema Array oder struct kann ich nur sagen: in diesem Fall bieten sich Array und struct an (wegen der Übersichtlichkeit), bei struct sollte man aber auf das Bytepadding achten, viele Compiler bieten aber hier was an.
    Also fachlich separate Werte gehören in jeweils ein eigenes Array und dann jeweils als struct-Element definieren, also in etwa

    typedef struct {
    char marker[2];
    char header[10];
    char data[500];
    } Bitmap;
    
    Bitmap bitmap={{0,1},{1,1,2,2},{99,88,77,...}};
    ...
    fwrite/fread(&bitmap,sizeof bitmap,1,fileptr);
    


  • mirrowwinger schrieb:

    Hmm warum beklagst du dich wegen dem einen Array? Wenn aufmerksam meinen letzten und den Beitrag davor gelesen hättest, dann wüsstest du, dass dieser mich quasi direkt aufgevordert hat NUR EIN Array und EIN Write zu nutzen. Da dies einer der wenigen Beiträge zu meiner Frage war, bin ich diesem nachgegangen. Wenn du einen besseren Tip hast, bin ich dir dafür dankbar. Was für Infos du meinst, kann ich mir vorstellen, habe mir ja das entsprechende Wiki angesehen und anschließend ein in OpenCV gespeichertes Bild genommen und danach dieses char-Array entwickelt. Warum ich z.B. Weite und Höhe in der Art speichere wird auch aus den Wikis/ einem Beispielbild klar. Ein Struct hilft mir ebenfalls nicht weiter, weil ich am Ende diesen String genau so in eine Datei schreiben muss (es funktioniert ja auch)! Das Struct bläht meinen Code nur aus und hat keinen weiteren Nutzen. (Du darfst mich natürlich gern korrigieren)

    keine ahnung, wer dir diesen müll empfiehlt.

    so macht man das normalerweise:

    typedef struct {
         short magic_number;
         unsigned int filesize;
         unsigned int reserved;
         unsigned int offset;
    } BMP_HEADER;
    

    mit der info-strutkur machst du das genauso.

    alles andere ist totaler schwachsinn.

    Wutz, was soll den das? kein mensch macht das mit einem array. ich sehe da auch überhauptkeinen vorteil.

    mach es einfach als struct, das du befüllst und dann in die datei schreibst.



  • Du hast keine Ahnung.



  • Wutz schrieb:

    Du hast keine Ahnung.

    doch.

    selbst die leute von linux-kernel machen es so, wenn sie ein neues dateisystem implementieren.
    keine ahnung, wo du das mit dem array aufgeschnappt hast! ich hab das noch nie gesehen!

    alle machen es so! und wenn du mir nicht glaubst, dann schau dir mal den quellcode von irgendwelche libs an!

    und nein, du wirst keine arrays für sowas finden.

    wahrscheinlich kommst du jetzt wieder mit der üblichen "little-endian/big-endian" sachen angeschissen.

    dazu noch ein wort: wer wirklich plattformunabhängig programmieren will, für den ist c eindeutig die falsche sprache. wer sowas machen will, braucht java, vielleicht auch python.

    außerdem kann ich das so entscheiden:

    #ifdef _BIG_ENDIAN_
    #define BMP_MAGIC 0x424D
    #endif
    
    #ifdef _LITTLE_ENDIAN_
    #define BMP_MAGIC 0x4D42
    #endif
    

    so what?

    ich finde, dass ist schon eine sehr linke tour, einem anfänger, der es nicht besser weiß, so einen müll einzureden.

    so wie du das am anfang hattest, was das im grude schon ok. du solltest bloß alle variablen in structs zusammenfassen.



  • mirrowwinger hast du jetzt verstanden, was zu tun ist?


Anmelden zum Antworten