C 不使用其他库生成BMP图片

本文介绍了一个简单的BMP图片处理程序,包括生成BMP文件及从BMP文件中获取位图数据的方法。通过C语言实现,提供了关键代码示例,便于读者理解和应用。

以下方法是从其他地方收集而来,并加以修改的结果。

头文件 bmp_image.h

 

#ifndef _LI_BITMAP_H_
#define _LI_BITMAP_H_ 
#pragma pack(push, 1) 
typedef unsigned char  U8;
typedef unsigned short U16;
typedef unsigned int   U32;
typedef struct tagBITMAPFILEHEADER{
	U16 bfType;
	U32 bfSize;
	U16 bfReserved1;
	U16 bfReserved2;
	U32 bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{
	U32 biSize;
	U32 biWidth;
	U32 biHeight;
	U16 biPlanes;
	U16 biBitCount;
	U32 biCompression;
	U32 biSizeImage;
	U32 biXPelsPerMeter;
	U32 biYPelsPerMeter;
	U32 biClrUsed;
	U32 biClrImportant;
} BITMAPINFOHEADER;

typedef struct tagRGBQUAD{
	U8 rgbBlue;
	U8 rgbGreen;
	U8 rgbRed;
	U8 rgbReserved;
} RGBQUAD;

typedef struct tagBITMAPINFO{
	BITMAPINFOHEADER bmiHeader;
	RGBQUAD bmiColors[1];
} BITMAPINFO;

#pragma pack(pop) 
#endif

main.c

 

#include "stdafx.h"
#include "bmp_image.h" // bmp_image header file. 
#define HEIGHT 640
#define WIDTH 480
//生成BMP图片(无颜色表的位图):在RGB(A)位图数据的基础上加上文件信息头和位图信息头
int GenBmpFile(U8 *pData, U8 bitCountPerPix, U32 width, U32 height, const char *filename);
//获取BMP文件的位图数据(无颜色表的位图):丢掉BMP文件的文件信息头和位图信息头,获取其RGB(A)位图数据
U8* GetBmpData(U8 *bitCountPerPix, U32 *width, U32 *height, const char* filename);
//释放GetBmpData分配的空间
void FreeBmpData(U8 *pdata);
//生成BMP图片(无颜色表的位图):在RGB(A)位图数据的基础上加上文件信息头和位图信息头  
int GenBmpFile(U8 *pData, U8 bitCountPerPix, U32 width, U32 height, const char *filename)  
{      
    FILE *fp;
	errno_t err;

	err = fopen_s(&fp,filename, "wb");
    if(err)      {          
		printf("fopen failed : %s, %d\n", __FILE__, __LINE__);
        return 0;
    }

    U32 bmppitch = ((width*bitCountPerPix + 31) >> 5) << 2;
	U32 filesize = bmppitch*height;
    BITMAPFILE bmpfile;
    bmpfile.bfHeader.bfType = 0x4D42;
    bmpfile.bfHeader.bfSize = filesize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmpfile.bfHeader.bfReserved1 = 0;
    bmpfile.bfHeader.bfReserved2 = 0;
    bmpfile.bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmpfile.biInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpfile.biInfo.bmiHeader.biWidth = width;
    bmpfile.biInfo.bmiHeader.biHeight = height;
    bmpfile.biInfo.bmiHeader.biPlanes = 1;
    bmpfile.biInfo.bmiHeader.biBitCount = bitCountPerPix;
    bmpfile.biInfo.bmiHeader.biCompression = 0;
    bmpfile.biInfo.bmiHeader.biSizeImage = 0;
    bmpfile.biInfo.bmiHeader.biXPelsPerMeter = 0;
    bmpfile.biInfo.bmiHeader.biYPelsPerMeter = 0;
    bmpfile.biInfo.bmiHeader.biClrUsed = 0;
    bmpfile.biInfo.bmiHeader.biClrImportant = 0;
    fwrite(&(bmpfile.bfHeader), sizeof(BITMAPFILEHEADER), 1, fp);
    fwrite(&(bmpfile.biInfo.bmiHeader), sizeof(BITMAPINFOHEADER), 1, fp);
    U8 *pEachLinBuf = (U8*)malloc(bmppitch);
    memset(pEachLinBuf, 0, bmppitch);
    U8 BytePerPix = bitCountPerPix >> 3;
    U32 pitch = width * BytePerPix;
    if(pEachLinBuf)      
	{          
		int h,w;
        for(h = height-1; h >= 0;h--)          
		{              
			for(w = 0; w < (int)width; w++)              
			{                 
				//copy by a pixel                  
				pEachLinBuf[w*BytePerPix+0] = pData[h*pitch + w*BytePerPix + 0];
                pEachLinBuf[w*BytePerPix+1] = pData[h*pitch + w*BytePerPix + 1];
                pEachLinBuf[w*BytePerPix+2] = pData[h*pitch + w*BytePerPix + 2];
            }
            fwrite(pEachLinBuf, bmppitch, 1, fp);
        }
        free(pEachLinBuf);
    }
    fclose(fp);
    return 1;
  }
    //获取BMP文件的位图数据(无颜色表的位图):丢掉BMP文件的文件信息头和位图信息头,获取其RGB(A)位图数据  
U8* GetBmpData(U8 *bitCountPerPix, U32 *width, U32 *height, const char* filename)  {     
	FILE *pf;
    errno_t err;
	err = fopen_s(&pf,filename, "rb");
    if(err)                   
	{         
		printf("fopen failed : %s, %d\n", __FILE__, __LINE__);
        return NULL;
    }

    BITMAPFILE bmpfile;
    fread(&(bmpfile.bfHeader), sizeof(BITMAPFILEHEADER), 1, pf);
    fread(&(bmpfile.biInfo.bmiHeader), sizeof(BITMAPINFOHEADER), 1, pf);
	// add by yuegy
    //print_bmfh(bmpfile.bfHeader);
    //print_bmih(bmpfile.biInfo.bmiHeader);
    if(bitCountPerPix)      
	{          
		*bitCountPerPix = (U8)bmpfile.biInfo.bmiHeader.biBitCount;
    }
    if(width)      
	{          
		*width = bmpfile.biInfo.bmiHeader.biWidth;
    }
    if(height)      
	{          
		*height = bmpfile.biInfo.bmiHeader.biHeight;
    }
	U32 bmppicth = (((*width)*(*bitCountPerPix) + 31) >> 5) << 2;
    U8 *pdata = (U8*)malloc((*height)*bmppicth);
    U8 *pEachLinBuf = (U8*)malloc(bmppicth);
    memset(pEachLinBuf, 0, bmppicth);
    U8 BytePerPix = (*bitCountPerPix) >> 3;
    U32 pitch = (*width) * BytePerPix;
    if(pdata && pEachLinBuf)      
	{          
		int w, h;
		for(h = (*height) - 1;h >= 0;h--)          
		{              
			fread(pEachLinBuf, bmppicth, 1, pf);
            for(w = 0;w < (int)(*width);w++)              
			{                  
				pdata[h*pitch + w*BytePerPix + 0] = pEachLinBuf[w*BytePerPix+0];
                pdata[h*pitch + w*BytePerPix + 1] = pEachLinBuf[w*BytePerPix+1];
                pdata[h*pitch + w*BytePerPix + 2] = pEachLinBuf[w*BytePerPix+2];
            }
        }
        free(pEachLinBuf);
    }
    fclose(pf);
    return pdata;
}
    //释放GetBmpData分配的空间  
void FreeBmpData(U8 *pdata)  {      
	if(pdata)      
	{          
		free(pdata);
        pdata = NULL;
    }
}

/**
 * 定义颜色结构体
 */
typedef struct _LI_RGB  {      
	U8 b;
    U8 g;
    U8 r;
}LI_RGB;

/**
 * 画点
 * pRGB 指针
 * position 点坐标
 * iImageH 图像高
 */
void drawPoint(LI_RGB* pRGB, POINT position, int iImageH)
{
 LI_RGB* tmp = pRGB+(position.y-m_FaceInfo.headArea.top-1)*iImageH+(position.x-m_FaceInfo.headArea.left-1);
 tmp->r = 255;
 tmp->g = 66;
 tmp->b = 51;
}

int main(char argc, char *argv[])  { 
//#if 1      
	//test one      
	LI_RGB pRGB[WIDTH][HEIGHT];// 定义位图数据      
	memset(pRGB, 0, sizeof(pRGB) );// 设置背景为黑色    
	int itemp = sizeof(pRGB);
	// 在中间画一个10*10的矩形      
	int i=0, j=0;
      for(i = 0; i < WIDTH; i++)      
	  {          
		  for( j = 0;j < 1; j++)          
		  {              
			  pRGB[i][j].b = 0xff;
              pRGB[i][j].g = 0x00;
              pRGB[i][j].r = 0x00;
          }
      }
      GenBmpFile((U8*)pRGB, 24, WIDTH, HEIGHT, "out.bmp");
//生成BMP文件     
//#endif       
//#if 1      //test two      
//	  U8 bitCountPerPix;
//      U32 width, height;
//      U8 *pdata = GetBmpData(&bitCountPerPix, &width, &height, "in.bmp");
//      if(pdata)      
//	  {          
//		  GenBmpFile(pdata, bitCountPerPix, width, height, "out1.bmp");
//          FreeBmpData(pdata);
//      }
//#endif             
	return 0;
}

 

 

转载于:https://my.oschina.net/guanyun/blog/69004

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值