Bitmap Breite durch 4 Teilbar
-
Ich möchte ein Bitmap erstellen, und es funktioniert ja auch super, wenn die eingegebene Breite durch 4 Teilbar ist. Aber wenn dies nicht der Fall ist, dann bekomme ich ein graues und verzerrtes Bild heraus. Ich habe zwar schon von Padding Bytes gelesen und auch selbst versucht diese hinzuzufügen, diese Versuche blieben aber leider ohne Erfolg.
Es wäre nett wenn mit jemand bei diesem Problem helfen könnte.
int createBitmap(char *output_file, int width, int height, struct figure *root) { // Initialize file FILE *bmp; unsigned long bmpsize; unsigned int hi, lo; // Size of the image (header included) bmpsize = width * height * 3 + 54; hi = bmpsize / 65536; lo = bmpsize % 65536; // Open the file if((bmp = fopen(output_file, "wb")) != NULL) { // Filetype (bitmap) unsigned char bitmaptype[2] = "BM"; unsigned char bmpsize2[4]; // Header length unsigned char headerlength[4] = "\x36\x0\x0\x0"; unsigned int bf_reserved_1 = 0; unsigned int bf_reserved_2 = 0; // Info header // Length (40 bytes, hexa: 28) unsigned char infolength[4] = "\x28\x0\x0\x0"; // Width in pixels unsigned long bi_width = width; // Height in pixels unsigned long bi_height = height; unsigned char bi_planes[2] = "\x01\x0"; unsigned char bi_bit_count[4] = "\x18\x0\x0\x0"; unsigned char bi_compression[2] = "\x0\x0"; unsigned char bi_size_image[4]; unsigned long bi_xpelspermeter = 0; unsigned long bi_ypelspermeter = 0; unsigned char bi_clr_used[4] = "\x0\x0\x0\x0"; unsigned char bi_clr_important[4] = "\x0\x0\x0\x0"; bmpsize2[0] = (int)lo%256; bmpsize2[1] = (int)lo/256; bmpsize2[2] = (int)hi%256; bmpsize2[3] = (int)hi/256; // Write BMPFILEHEADER fwrite(&bitmaptype, 2, 1, bmp); fwrite(&bmpsize2, 4, 1, bmp); fwrite(&bf_reserved_1, 2, 1, bmp); fwrite(&bf_reserved_2, 2, 1, bmp); fwrite(&headerlength, 4, 1, bmp); bi_size_image[0] = (int)lo % 256; bi_size_image[1] = (int)lo / 256; bi_size_image[2] = (int)hi % 256; bi_size_image[3] = (int)hi / 256; // DWORD value bmpsize = width * height; // multiplicated with 3 originally // Write BMPINFOHEADER fwrite(&infolength, 4, 1, bmp); fwrite(&bi_width, 4, 1, bmp); fwrite(&bi_height, 4, 1, bmp); fwrite(&bi_planes, 2, 1, bmp); fwrite(&bi_bit_count, 4, 1, bmp); fwrite(&bi_compression, 2, 1, bmp); fwrite(&bi_size_image, 4, 1, bmp); fwrite(&bi_xpelspermeter, 4, 1, bmp); fwrite(&bi_ypelspermeter, 4, 1, bmp); fwrite(&bi_clr_used, 4, 1, bmp); fwrite(&bi_clr_important, 4, 1, bmp); } // Write RGB values (for each figure and for each pixel) struct figure *temp_pt = root; struct figure *temp_nxt = root->next; int height_counter = 1; int width_counter = 1; // Initialize file_stream with enough size //char *file_stream[(height * width) + ((height * width) % 4)]; int long file_stream_dimension = height * width; // char *file_stream[(width * height)]; char *file_stream[file_stream_dimension]; // Make file_stream all black int counter = 0; for(counter = 0; counter < file_stream_dimension; counter++) { file_stream[counter] = (char[3]){0,0,0}; } while(temp_nxt != NULL) { // Start drawing for(height_counter = 1; height_counter <= height; height_counter++) { for(width_counter = 1; width_counter <= width; width_counter++) { // Declare current X and Y coordinates (remember that Y = 0 means at the top, because the bitmap is rising from the bottom!) int x_cur = width_counter; int y_cur = height - height_counter + 1; int cur_pixel = x_cur + (height - y_cur) * width; // Current figure is a rectangle if(temp_nxt->type == 0) { // Start collision detection int matches_x = 0; int matches_y = 0; if(x_cur > temp_nxt->x && x_cur <= (temp_nxt->x + temp_nxt->width)) { matches_x = 1; } if(y_cur <= temp_nxt->y + temp_nxt->height && y_cur > temp_nxt->y) { matches_y = 1; } if(matches_x && matches_y) { int r = hexToInt(temp_nxt->color, 0); // RED int g = hexToInt(temp_nxt->color, 1); // GREEN int b = hexToInt(temp_nxt->color, 2); // BLUE file_stream[cur_pixel - 1] = (char[3]){b, g, r}; } } // Current figure is a circle else if(temp_nxt->type == 1) { // Start collision detection int x_condition = (x_cur - temp_nxt->x) * (x_cur - temp_nxt->x); int y_condition = (y_cur - temp_nxt->y) * (y_cur - temp_nxt->y); int condition = x_condition + y_condition; if(condition < (temp_nxt->radius * temp_nxt->radius)) { int r = hexToInt(temp_nxt->color, 0); // RED int g = hexToInt(temp_nxt->color, 1); // GREEN int b = hexToInt(temp_nxt->color, 2); // BLUE file_stream[cur_pixel - 1] = (char[3]){b, g, r}; } } // Current figure is a triangle # THIS COLLISION DETECTION DOES NOT WORK PROPERLY YET. MODIFY ax, ay,... DATA AND/OR MODIFY x_cur AND/OR y_cur. else if(temp_nxt->type == 2) { // Start collision detection int ax = temp_nxt->ax; int ay = temp_nxt->ay; int bx = temp_nxt->bx; int by = temp_nxt->by; int cx = temp_nxt->cx; int cy = temp_nxt->cy; int con_1 = (x_cur - bx) * (ay - by) - (ax - bx) * (y_cur - by); int con_2 = (x_cur - cx) * (by - cy) - (bx - cx) * (y_cur - cy); int con_3 = (x_cur - ax) * (cy - ay) - (cx - ax) * (y_cur - ay); if(con_1 < 0.0f && con_2 < 0.0f && con_3 < 0.0f) { int r = hexToInt(temp_nxt->color, 0); // RED int g = hexToInt(temp_nxt->color, 1); // GREEN int b = hexToInt(temp_nxt->color, 2); // BLUE file_stream[cur_pixel - 1] = (char[3]){b, g, r}; } else if(con_1 > 0.0f && con_2 > 0.0f && con_3 > 0.0f) { int r = hexToInt(temp_nxt->color, 0); // RED int g = hexToInt(temp_nxt->color, 1); // GREEN int b = hexToInt(temp_nxt->color, 2); // BLUE file_stream[cur_pixel - 1] = (char[3]){b, g, r}; } } } } while(temp_nxt != temp_pt) { temp_pt = temp_pt->next; } temp_pt = root; temp_nxt = temp_nxt->next; } // Write to file counter = 0; for(counter = 0; counter < (width * height); counter++) { fwrite(file_stream[counter], 3, 1, bmp); } free(root); fclose(bmp); return 0; }
-
Deine (viel zu lange) Funktion zu analysieren, hat hier keiner Lust.
Stelle konkrete Fragen zu C und nicht nebulöse Vermutungen zu deinem BMP Code an.