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.


Anmelden zum Antworten