#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include “bmpfile.h”
#pragma pack(2)
typedef struct {
unsigned char bfType[2];
unsigned int bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned int bfOffBits;
} BMPFileHeader;
#pragma pack(2)
typedef struct {
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BMPInfoHeader;
typedef struct {
BMPFileHeader fileHeader;
BMPInfoHeader infoHeader;
int stride;
unsigned char *imageData;
} BMPImage;
void* bmpfile_create(int w, int h) {
BMPImage *bmpImage = malloc(sizeof(BMPImage));
if ( !bmpImage->imageData )
printf(" BMP image creation failed\n ");
bmpImage->fileHeader.bfType[0] = ‘B’;
bmpImage->fileHeader.bfType[1] = ‘M’;
bmpImage->fileHeader.bfSize = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + w * h * 3;
bmpImage->fileHeader.bfReserved1 = 0;
bmpImage->fileHeader.bfReserved2 = 0;
bmpImage->fileHeader.bfOffBits = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);
bmpImage->infoHeader.biSize = sizeof(BMPInfoHeader);
bmpImage->infoHeader.biWidth = w;
bmpImage->infoHeader.biHeight = h;
bmpImage->infoHeader.biPlanes = 1;
bmpImage->infoHeader.biBitCount = 24;
bmpImage->infoHeader.biCompression = 0;
bmpImage->infoHeader.biSizeImage = w * h * 3;
bmpImage->infoHeader.biXPelsPerMeter = 0;
bmpImage->infoHeader.biYPelsPerMeter = 0;
bmpImage->infoHeader.biClrUsed = 0;
bmpImage->infoHeader.biClrImportant = 0;
bmpImage->stride = (((bmpImage->infoHeader.biWidth * bmpImage->infoHeader.biBitCount) + 31) / 32) * 4;
bmpImage->imageData = malloc(bmpImage->stride * bmpImage->infoHeader.biHeight * 3);
return bmpImage;
}
void bmpfile_destroy(void *ctx) {
BMPImage bmpImage = (BMPImage)ctx;
free(bmpImage->imageData);
free(bmpImage);
}
void* bmpfile_load(char *file) {
FILE *fp = fopen(file, “rb”);
if (fp == NULL) {
return NULL;
}
BMPImage *bmpImage = malloc(sizeof(BMPImage));
fread(&(bmpImage->fileHeader), sizeof(BMPFileHeader), 1, fp);
fread(&(bmpImage->infoHeader), sizeof(BMPInfoHeader), 1, fp);
bmpImage->imageData = malloc(bmpImage->infoHeader.biSizeImage);
fseek(fp, bmpImage->fileHeader.bfOffBits, SEEK_SET);
fread(bmpImage->imageData, bmpImage->infoHeader.biSizeImage, 1, fp);
fclose(fp);
return bmpImage;
}
int bmpfile_save(void *ctx, char *file) {
BMPImage bmpImage = (BMPImage)ctx;
FILE *fp = fopen(file, “wb”);
if (fp == NULL) {
return -1;
}
fwrite(&(bmpImage->fileHeader), sizeof(BMPFileHeader), 1, fp);
fwrite(&(bmpImage->infoHeader), sizeof(BMPInfoHeader), 1, fp);
fwrite(bmpImage->imageData, bmpImage->infoHeader.biSizeImage, 1, fp);
fclose(fp);
return 0;
}
void bmpfile_pixel(void *ctx, int x, int y, int c) {
if (ctx == NULL)
return;
BMPImage bmpImage = (BMPImage)ctx;
if ( x < 0 || x >= bmpImage->infoHeader.biWidth || y < 0 || y >= bmpImage->infoHeader.biHeight )
return;
int index = (bmpImage->infoHeader.biHeight - y - 1) * bmpImage->stride + x;// bmpImage->infoHeader.biWidth + x;//按照反的方向存储(从左向右,从下向上)图片的最左下角的像素是首先被存储在bmp文件中的,所以这里代码的最后是加+x
bmpImage->imageData[index * 3 + 0] = c & 0xFF;
bmpImage->imageData[index * 3 + 1] = (c >> 8) & 0xFF;
bmpImage->imageData[index * 3 + 2] = (c >> 16) & 0xFF;
}
int main() {
srand((unsigned)time(NULL));
int width = 400;
int height = 300;
void *ctx = bmpfile_create(width, height);
int i;
for (i = 0; i < 1000; i++) {
int x = rand() % width;
int y = rand() % height;
int r = rand() % 256;
int g = rand() % 256;
int b = rand() % 256;
int color = r | (g << 8) | (b << 16);
bmpfile_pixel(ctx, x, y, color);
}
bmpfile_save(ctx, "test.bmp");
bmpfile_destroy(ctx);
return 0;
}