Bitmap erzeugen mit Pixelbreite nicht durch 4 teilbar



  • ja und laut dem schreibt er schon die daten korrekt in den array. ich weiß nur nicht wie sin in der datei ausgewertet werden.



  • Deine zweite for-Schleife sollte sich nur durch Start- und Endwert der Breite unterscheiden:

    d=B+4-c;
    for(i=B;B<(d);i++)
    {
        for(j=0;j<H;j++)
        {
            farben[i][j]=(RGBTRIPLE *)malloc(sizeof(RGBTRIPLE));
            farben[i][j]->rgbtBlue=0;
            farben[i][j]->rgbtGreen=0;
            farben[i][j]->rgbtRed=0;
        }
    }
    

    Was mir sonst noch aufgefallen ist:
    Du forderst für jedes Pixel Speicher via malloc an. 204x150 mal 3 Byte.
    Wäre es nicht sinnvoller EIN Speicherbereich für das Bild zu nehmen?
    Zudem gibst du diesen Speicher nicht frei.

    Für ein einfarbiges Bild reicht es aber auch ein Pixel 204x150 mal auszugeben.
    Die Extrapixel können dann auch die gleiche Farbe haben.



  • könntest du mir das mit dem speicher zeigen wie das geht? ich hab rum probiert, bin aber an dem 2d array irgendwie gescheitert.

    Wenn ich das so eingebe, stürzt es ab. bei B darf er ja denk ich auch nicht anfangen, weil das ja die letzte Pixelspalte ist, die noch die farbe haben sollte. also B+1 oder?

    Wie ist das? Ich habe ein 3x3 pixel bild, mit einer einheitlichen farbe:

    0xff 0xff 0xff 0x00
    0xff 0xff 0xff 0x00
    0xff 0xff 0xff 0x00

    wäre das so korrekt?



  • Deine zweite for-Schleife sollte sich nur durch Start- und Endwert der Breite unterscheiden:

    d=B+4-c;
    for(i=B;B<(d);i++)
    {
        for(j=0;j<H;j++)
        {
            farben[i][j]=(RGBTRIPLE *)malloc(sizeof(RGBTRIPLE));
            farben[i][j]->rgbtBlue=0;
            farben[i][j]->rgbtGreen=0;
            farben[i][j]->rgbtRed=0;
        }
    }
    

    Was mir sonst noch aufgefallen ist:
    Du forderst für jedes Pixel Speicher via malloc an. 204x150 mal 3 Byte.
    Wäre es nicht sinnvoller EIN Speicherbereich für das Bild zu nehmen?
    Zudem gibst du diesen Speicher nicht frei.

    Für ein einfarbiges Bild reicht es aber auch ein Pixel 204x150 mal auszugeben.
    Die Extrapixel können dann auch die gleiche Farbe haben.



  • Rückgabewerte von Funktionen, die durchaus schief gehen können, sollten tunlichst überprüft werden.
    Wenn du das gemacht hättest, hättest du folgenden Fehler wahrscheinlich sofort als solchen erkannt:

    fin = fopen("D:\unbenannt.bmp","w");
    //-> Escape-Sequenz beachten
    fin = fopen("D:\\unbenannt.bmp","w");
    


  • Vicious Falcon schrieb:

    Rückgabewerte von Funktionen, die durchaus schief gehen können, sollten tunlichst überprüft werden.
    Wenn du das gemacht hättest, hättest du folgenden Fehler wahrscheinlich sofort als solchen erkannt:

    fin = fopen("D:\unbenannt.bmp","w");
    //-> Escape-Sequenz beachten
    fin = fopen("D:\\unbenannt.bmp","w");
    

    Danke für den Tipp, leider ändert das an der funktion des programms nichts.



  • Sorry für den Doppelpost (Empfangsprobleme 😞 )

    Zu B: Deine erste Schleife geht von 0 bis < B, B wird also nicht erreicht. (von 0 bis 200 sind 201 Punkte)

    RGBTRIPLE farben[150][204];
    
    farben[h][b].rgbtBlue = 32;
    

    Evtl. musst du dieses Array auch mit packed kennzeichnen oder 32-bit Farbtiefe nehmen.



  • zu B: hast recht 🙂

    alles klar ich probier ein wenig rum. danke erstmal



  • Ich gebe dir einmal ein kleines, hoffentlich funktionierendes Beispiel

    int WriteBmp(const char* pFilename, unsigned int w, unsigned int h, unsigned int bc, char* pbits, int len)
    {
    	FILE *fin;
    	BITMAPFILEHEADER bfh;
    	BITMAPINFOHEADER bih;
    	fin = fopen(pFilename,"w");
    	if(!fin)
    		return 0;
    	memset(&bfh, 0, sizeof(BITMAPFILEHEADER));
    	memset(&bih, 0, sizeof(BITMAPINFOHEADER));
    	bfh.bfType = 19778;
    	bih.biSize		= sizeof(BITMAPINFOHEADER);
    	bih.biPlanes = 1;
    	bih.biSizeImage	= (h)*((w*(bc / 8) + 3) & ~3);
    	bih.biWidth= w;
    	bih.biHeight= h;
    	bfh.bfSize = sizeof(bfh);
    	bfh.bfSize+= h*4*((w*bc+31)/32);
    	bfh.bfSize+= sizeof(BITMAPINFOHEADER);
    	bfh.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
    	bih.biBitCount= bc;
    	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fin);
    	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fin);
    	fwrite(pbits,len,1,fin);
    	fclose(fin);
    	return 1;
    }
    
    int main()
    {
    	RGBTRIPLE *farben;
    	long B=201, H=150;
    	unsigned short farbtiefe = 24;
    	int sizeImg;
    
    	sizeImg = (H)*((B*(farbtiefe / 8) + 3) & ~3);
    	farben = malloc(sizeof(RGBTRIPLE)*sizeImg);
    	if(!farben)
    		return 0;
    	memset(farben,0xFF,sizeof(RGBTRIPLE)*sizeImg);
    
    	WriteBmp("d:\\unb.bmp",B,H,24,(char*)farben,sizeImg);
        free(farben);
        return 0;
    }
    

    Die ein oder andere Klammer ist überflüssig. Der Speicher wird nur einmal angefordert und jedes Byte auf 0xFF gesetzt. Das Resultat ist daher ein komplett weißes Bitmap.
    Die Größe des Speichers wird der Einfachheit halber mit übergeben.

    Edit: Nicht benötigte Variablen entfernt (Copy & Pasteproblem)
    Man, da waren ja noch mehr 🙄



  • Super danke, das geht auf jeden fall, vielen dank.



  • Zu den Füllbytes die benötigt werden, um auf eine durch vier teilbare Breite zu kommen, möchte ich anmerken, dass es egal ist welchen Wert sie haben. Du kannst da auch deine geheimen Botschaften drin verstecken. Sie werden einfach nur nicht angezeigt. Interessant könnte es nur werden, wenn du mit Filtern, die die Umgebungspixel auswerten, arbeitest. Die dürfen aber auch bei schwarzen Pixel nicht den Rand mit einbeziehen.


Anmelden zum Antworten