Reputation: 3
This is my code for a bitmap image but it dosen't work and I have no idea why. I previously did something the same but I was reading an original bitmap and I had only to change its colors. The code was exactly the same thought and it did work that time but for reading an image from 0 it seems it didn't work. I searched a lot on the internet for answers and i think maybe it's a problem with data from headers or something about padding. Can you help me, please?
Header:
#pragma pack(1)
struct bmp_fileheader
{
unsigned char fileMarker1; /* 'B' */
unsigned char fileMarker2; /* 'M' */
unsigned int bfSize; /* File's size */
unsigned short unused1;
unsigned short unused2;
unsigned int imageDataOffset; /* Offset to the start of image data */
};
struct bmp_infoheader
{
unsigned int biSize; /* Size of the info header - 40 bytes */
signed int width; /* Width of the image */
signed int height; /* Height of the image */
unsigned short planes;
unsigned short bitPix;
unsigned int biCompression;
unsigned int biSizeImage; /* Size of the image data */
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
};
#pragma pack()
Code:
#include <stdio.h>
#include <stdlib.h>
#include "bmp_header.h"
typedef struct {
unsigned char b;
unsigned char g;
unsigned char r;
}rgb;
int main() {
int i, j, k;
struct bmp_fileheader a;
struct bmp_infoheader b;
FILE * p = fopen("img.bmp", "wb");
a.fileMarker1 = 'B';
a.fileMarker2 = 'M';
a.unused1=0;
a.unused2=0;
a.bfSize = 54+3*40*40;
a.imageDataOffset=54;
b.biSize = 40;
b.width = 40;
b.width = 40;
b.planes = 1;
b.bitPix = 24;
b.biCompression = 0;
b.biSizeImage = 4*40*40;
b.biXPelsPerMeter = 0;
b.biYPelsPerMeter = 0;
b.biClrUsed = 0;
b.biClrImportant = 0;
rgb matrix[40][40];
for (i = 0; i < 10; i++) {
for (j = 0; j < 40; j++) {
matrix[i][j].b = 255;
matrix[i][j].g = 255;
matrix[i][j].r = 255;
}
}
for (i = 10; i < 30; i++) {
for (j = 0; j < 40; j++) {
if (j < 10 || j > 29) {
matrix[i][j].b = 255;
matrix[i][j].g = 255;
matrix[i][j].r = 255;
} else {
matrix[i][j].b = 255;
matrix[i][j].g = 255;
matrix[i][j].r = 0;
}
}
}
for (i = 30; i < 40; i++) {
for (j = 0; j < 40; j++) {
matrix[i][j].b = 255;
matrix[i][j].g = 255;
matrix[i][j].r = 255;
}
}
fwrite( & a, sizeof(a), 1, p);
fwrite( & b, sizeof(b), 1, p);
int t = (4 - (40 * 3)%4)%4;//padding equation found on the internet
for(i = 0; i < 40; i++){
for(j = 0; j < 40; j++)
fwrite(&matrix[i][j], sizeof(matrix[i][j]), 1, p);
for(k = 0; k < t; k++){
putc(0,p); //padding
}
}
fclose(p);
}
Upvotes: 0
Views: 91
Reputation: 25266
The scanline size is calculated as:
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
The biSizeImage
field is computed as:
b.biSizeImage= WIDTHBYTES(xRes*24) * yRes;
The 24
is the number of bits per pixel.
You also set b.width
twice. The second one should be height
.
fheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + 0/*no palette for 24 bits color*/;
fheader.bfSize = fheader.bfOffBits + iheader.biSizeImage;
Upvotes: 1