接上篇,既然颜色表可以得到,bmp的文件格式已经很清楚了,能否自己创建bmp文件呢?

还是以256色bmp为例.

答案是可以的,这是程序生成的一个简单的bmp:

BMP格式学习之创建bmp文件_第1张图片

根据之前的颜色表,可以得到red,green,blue像素对应的index,只要在位图数据区写上该内容就好了。

注意位图数据的方向是从左到右从下至上。

Code Snippet
  1. /*
  2. * =====================================================================================
  3. *       Filename:  CreateBMPFile.cpp
  4. *    Description:  demos of creating 256BMP file
  5. *
  6. *        Version:  1.0
  7. *        Created:  03/09/2013 03:44:13 PM
  8. *
  9. *         Author:  zhy (), [email protected]
  10. * =====================================================================================
  11. */
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "Defs.h"
  16.  
  17. int main()
  18. {
  19.     const int width = 200;
  20.     const int height = 300;
  21.     const int bitCount = 8;
  22.  
  23.     int realWidth = (width * bitCount + 31)/8;
  24.     realWidth = realWidth/4*4;
  25.     const int dataSize = realWidth * height;
  26.  
  27.     BitMapFileHeader bmfHeader;
  28.     memset(&bmfHeader, 0, sizeof(bmfHeader));
  29.     bmfHeader.bfType = 0x4d42;
  30.     bmfHeader.bfOffBits = sizeof(BitMapFileHeader) + sizeof(BitMapInfoHeader) + sizeof(RGBQuad)*256;
  31.     bmfHeader.bfSize = bmfHeader.bfOffBits + dataSize;
  32.  
  33.     BitMapInfoHeader bmiHeader;
  34.     memset(&bmiHeader, 0, sizeof(bmiHeader));
  35.     bmiHeader.biSize = sizeof(BitMapInfoHeader);
  36.     bmiHeader.biWidth = width;
  37.     bmiHeader.biHeight = height;
  38.     bmiHeader.biPlanes = 1;
  39.     bmiHeader.biBitCount = bitCount;
  40.     bmiHeader.biSizeImage = dataSize;
  41.  
  42.     FILE* fpIn = fopen("3.bmp", "r");//3.bmp是之前测试用的文件,256色bmp
  43.     if (!fpIn)
  44.         return -1;
  45.  
  46.     RGBQuad colorTables[256];
  47.     fseek(fpIn, 0x36, SEEK_SET);
  48.     fread(colorTables, sizeof(RGBQuad), 256, fpIn);
  49.     fclose(fpIn);
  50.  
  51.     unsigned char* imageData = (unsigned char*)malloc(dataSize*sizeof(unsigned char));
  52.     if (!imageData)
  53.         return -1;
  54.  
  55.     memset(imageData, 0, dataSize);
  56.     for (int i=0; i<realWidth; ++i)
  57.     {
  58.         for (int j=0; j<=20; ++j)
  59.         {
  60.             imageData[j*realWidth + i] = 0xff;//white
  61.         }
  62.  
  63.         for (int j=50; j<=100; ++j)
  64.         {
  65.             imageData[j*realWidth + i] = 0xfc;//blue
  66.         }
  67.  
  68.         for (int j=150; j<=180; ++j)
  69.         {
  70.             imageData[j*realWidth + i] = 0xfa;//green
  71.         }
  72.  
  73.         for (int j=220; j<300; ++j)
  74.         {
  75.             imageData[j*realWidth + i] = 0xf9;//red
  76.         }
  77.     }
  78.  
  79.     FILE* fpOut = fopen("demo.bmp", "w");
  80.     if (!fpOut)
  81.         return -1;
  82.  
  83.     fwrite(&bmfHeader, sizeof(bmfHeader), 1, fpOut);
  84.     fwrite(&bmiHeader, sizeof(bmiHeader), 1, fpOut);
  85.     fwrite(colorTables, sizeof(RGBQuad), 256, fpOut);
  86.     fwrite(imageData, 1, dataSize, fpOut);
  87.     fclose(fpOut);
    free(imageData);
  88. }

该代码会生成上述bmp文件。

如果你看了前面的文章,就别问我3.bmp哪里的^_^

因为数据方向从上到下,因此从下到上依次为white, blue, green, red。

既然数据可以这么写入,接下来的就可以自己玩啦。

比如写入的代码改成了这个样子:

Code Snippet
  1. int i = 0;
  2.   while (i++ < 100)
  3.   {
  4.       int randX = rand()%realWidth;
  5.       int randY = rand()%height;
  6.       int randColorIndex = rand()%256;
  7.       const int range = 15;
  8.  
  9.       int minX = randX - range;
  10.       minX = minX > 0 ? minX : 0;
  11.       int minY = randY - range;
  12.       minY = minY > 0 ? minY : 0;
  13.       int maxX = randX + range;
  14.       maxX = maxX > realWidth ? realWidth : maxX;
  15.       int maxY = randY + range;
  16.       maxY = maxY > height ? height : maxY;
  17.  
  18.       printf("%d,%d,%d,%d\n",minX, maxX, minY, maxY);
  19.       for (int i=minX; i<maxX; ++i)
  20.           for (int j=minY; j<maxY; ++j)
  21.           {
  22.               imageData[j*realWidth + i] = randColorIndex;
  23.           }
  24.   }

随机取点,以该点为中心的矩形随机填充颜色。就成了这个样子:

BMP格式学习之创建bmp文件_第2张图片

是不是很好玩?绘制直线,圆形应该就很容易了。