Сначала объявите три типа инициализаторов, которые вы будете в основном использовать:
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;
Что касается структур, я предлагаю вам использовать три, каждый для элемента BMP:
typedef struct BITMAPINFOHEADER
{
dword bmp_size;
word bmp_app1;
word bmp_app2;
dword bmp_offset;
} BMP;
typedef struct DIB_HEADER
{
dword dib_size;
dword dib_w;
dword dib_h;
word dib_planes;
word dib_bits;
dword dib_compression;
dword dib_rawsize;
dword dib_xres;
dword dib_yres;
dword dib_palette;
dword dib_important;
} DIB;
typedef struct PIXEL_ARRAY
{
byte B;
byte G;
byte R;
} PIX;
Тогда вы можете манипулировать изображением разными способами.Вы можете создать 1D / 2D массив для хранения данных или просто манипулировать bmp напрямую.Следующий код создает 500x460 цветных пустых bmp напрямую:
void new (char NAME[] , byte RED , byte GREEN , byte BLUE)
{
char build_name[256];
const char* id = "BM";
int i, j;
char debug[128];
FILE* fp;
dword rsize = (500 * sizeof(PIX) + 3) / 4 * 4;
dword pad = rsize - 500 * sizeof(PIX);
dword rawsize = rsize * 460 * sizeof(PIX);
byte zero[3] = {0};
dword size = (2) + sizeof(BMP) + sizeof(DIB) + sizeof(PIX);
BMP bmp[] = { 2+sizeof(BMP)+sizeof(DIB)+(sizeof(rawsize)/4), 0, 0, 2+sizeof(BMP)+sizeof(DIB) }; //2+ [!]
DIB dib[] = { sizeof(DIB), 500, 460, 1, 24, 0, (sizeof(rawsize)/4), 2835, 2835, 0, 0 };
PIX pix;
pix.R = RED;
pix.G = GREEN;
pix.B = BLUE;
sprintf(build_name, "%s.bmp", NAME);
fp = fopen(build_name, "wb");
if(!fp) strcpy(debug, "Access Denied.");
else strcpy(debug, "Saved.");
fwrite(id, 1, 2, fp);
fwrite(&bmp, 1, sizeof(bmp), fp);
fwrite(&dib, 1, sizeof(dib), fp);
for(i = 0; i < 460; i++)
{
for(j = 0; j < 500; j++)
{
fwrite(&pix, sizeof(pix), 1, fp);
}
if (pad) fwrite(zero, 1, pad, fp);
}
fclose(fp);
}
Точка использует fseek()
для определения местоположения пикселя и fwrite()
для прямой записи пикселей.