Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1613046
  • 博文数量: 441
  • 博客积分: 20087
  • 博客等级: 上将
  • 技术积分: 3562
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-19 15:35
文章分类

全部博文(441)

文章存档

2014年(1)

2012年(1)

2011年(8)

2010年(16)

2009年(15)

2008年(152)

2007年(178)

2006年(70)

分类: C/C++

2008-12-15 12:37:42

纯手写bmp图片一文中,我们用16进制编辑器纯手工写出了一个16*16大小的24位色的bmp图片,通过文章的分析,你会发现,只要正确填充了bmp文件的头部,就能够显示出一幅bmp图片,虽然图片的内容看起来可能毫无意义。纯手工写bmp图片时,因为各种计算和输入的错误,很可能导致写出的图片不正确,这种做起来效率也很低,很麻烦,今天,我们就在此基础上,用程序生成一个任意大小的bmp图片。

关于bmp图片的各个结构的分析,在纯手写bmp图片一文中讲的很详细, 在此,不再重复,这里,只给出本人写的生成bmp图片的源代码:


// CreateBmp24.c


#include <stdio.h>
#include <windows.h>
#include <time.h>

void CreateBmp24(unsigned int width, unsigned int height);

int main(int argc, char **argv)
{
    int width;
    int heigth;

    if ( argc != 3)
    {
        printf("Usage %s width height\n", argv[0]);
        printf("Example:\n\t%s 16 16\n", argv[0]);
        return -1;
    }

    // get the width and height from the command line

    width = atoi(argv[1]);
    heigth = atoi(argv[2]);

    CreateBmp24(width, heigth);

    return 0;
}

void CreateBmp24(unsigned int width, unsigned int height)
{
    char szFileName[32];
    time_t ltime;
    struct tm* pnow;
    HANDLE hFile;
    BYTE *pData = NULL;
    int i, num;
    BITMAPFILEHEADER bmfHdr;
    BITMAPINFOHEADER bi;
    DWORD dwBytesWrite;

    if ( width <= 0 || height <= 0 )
        return;

    // allocate memory for data area

    pData = (BYTE*)malloc(width * height * 3);
    if ( pData == NULL )
        return;

    // generate random data

    srand((unsigned)time(NULL));
    for ( i = 0; i < (int)(width * height * 3); i++)
    {
        do
        {
            num = rand( ); // generate number between 0 and 255

        } while (num < 0 || num > 255);
        pData[i] = num;
    }

    // initialize the structures

    RtlZeroMemory(&bmfHdr, sizeof(bmfHdr));
    RtlZeroMemory(&bi, sizeof(bi));

    // fill the necessary struct fields of the BITMAPFILEHEADER

    bmfHdr.bfType = 0x4d42; // "BM"

    bmfHdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + width * height * 3;
    bmfHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    // fill the necessary struct fields of the BITMAPINFOHEADER

    bi.biSize = sizeof(bi);
    bi.biBitCount = 24;
    bi.biHeight = height;
    bi.biWidth = width;
    bi.biCompression = BI_RGB;    
    bi.biPlanes = 1;
    

    /* according current date and time to generate file name, saved in c:\ */
    time(&ltime);
    pnow = localtime(&ltime);
    wsprintf(szFileName, "C:\\%04d%02d%02d-%02d%02d%02d.bmp", pnow->tm_year, pnow->tm_mon, pnow->tm_mday,
            pnow->tm_hour, pnow->tm_min, pnow->tm_sec);

    // create the bmp file

    hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if ( hFile == INVALID_HANDLE_VALUE )
    {
        free(pData);
        return;
    }

    // write the BITMAPFILEHEADER

    WriteFile(hFile, &bmfHdr, sizeof(BITMAPFILEHEADER), &dwBytesWrite, NULL);
    // write the BITMAPINFOHEADER

    WriteFile(hFile, &bi, sizeof(BITMAPINFOHEADER), &dwBytesWrite, NULL);
    // write the bmp data

    WriteFile(hFile, pData, width * height * 3, &dwBytesWrite, NULL);
    
    // release resources

    CloseHandle(hFile);
    free(pData);

    printf("The bmp file is %s\n", szFileName);
}


代码中有比较详细的注释,而且也不难,所以,就不再详细说明了。

用VC6新建立一个Win32 Console Application,选择空工程,然后把上述文件加入,编译一下,在命令行运行,比如:
C:\>CreateBmp24.exe 256 256
你就会得到一个256*256大小的24色位图,文件默认保存在C:\下面,文件名是根据当前的日期和时间自动生成的。

Author: thinker
QQ: 94483026
E-Mail:cnhnyugmailcom

阅读(2857) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~