C++将内存中的位图(位图句柄)保存成bmp位图文件(附源码)

       有时我们可能需要将内存中HBITMAP位图句柄指向的位图,保存成bmp位图文件。我们可以调用一些GDI函数以及操作文件的函数,来实现这一功能,相关代码如下:

// 保存位图到文件中
BOOL SaveHBitmapToBmpFile( HBITMAP hBmp, LPCTSTR lpfilename, DWORD dwDefaultDpi/* = 32*/)
{
	if ( NULL == hBmp || NULL == lpfilename )
	{
		return FALSE;
	}

	HDC hdc = NULL;        // 设备描述表   
	int ibits = 0;;     
	WORD wbitcount = 0;    // 当前显示分辨率下每个像素所占字节数   

	// 位图中每个像素所占字节数,定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数   
	DWORD dwpalettesize=0, dwbmbitssize, dwdibsize, dwwritten;   

	BITMAP bitmap;           // 位图属性结构   
	BITMAPFILEHEADER bmfhdr; // 位图文件头结构   
	BITMAPINFOHEADER bi;     // 位图信息头结构   
	LPBITMAPINFOHEADER lpbi; // 指向位图信息头结构   

	// 定义文件,分配内存句柄,调色板句柄   
	HANDLE hfile, hdib, hpal, holdpal = NULL;   

	// 计算位图文件每个像素所占字节数   
	hdc = CreateDC( _T("DISPLAY"), NULL, NULL, NULL );   
	ibits = GetDeviceCaps( hdc, BITSPIXEL ) *
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是C语言实现24位图转换1位位图的源代码: ```c #include<stdio.h> #include<stdlib.h> #pragma pack(2) typedef struct tagBITMAPFILEHEADER { unsigned short bfType; unsigned int bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned int bfOffBits; }BITMAPFILEHEADER; #pragma pack(2) typedef struct tagBITMAPINFOHEADER { 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; }BITMAPINFOHEADER; typedef struct tagRGBQUAD { unsigned char rgbBlue; unsigned char rgbGreen; unsigned char rgbRed; unsigned char rgbReserved; }RGBQUAD; typedef struct tagRGBTRIPLE { unsigned char rgbtBlue; unsigned char rgbtGreen; unsigned char rgbtRed; }RGBTRIPLE; int main(int argc,char *argv[]) { if(argc!=3) { printf("Usage:%s <input_file> <output_file>\n",argv[0]); return -1; } char *input_file=argv[1]; char *output_file=argv[2]; FILE *fp_in=fopen(input_file,"rb"); if(fp_in==NULL) { printf("Open input file error!\n"); return -1; } BITMAPFILEHEADER file_header; BITMAPINFOHEADER info_header; RGBTRIPLE *p_rgb_buffer=NULL;//24位色图像缓冲区 unsigned char *p_mono_buffer=NULL;//1位色图像缓冲区 fread(&file_header,sizeof(BITMAPFILEHEADER),1,fp_in); fread(&info_header,sizeof(BITMAPINFOHEADER),1,fp_in); //判断位图类型是否为24位色图像 if(info_header.biBitCount!=24) { printf("Input file is not a 24-bit color bitmap!\n"); fclose(fp_in); return -1; } //计算24位色图像每行的字节数 int row_size=(info_header.biWidth*info_header.biBitCount+31)/32*4; //分配24位色图像缓冲区 p_rgb_buffer=(RGBTRIPLE*)malloc(row_size*info_header.biHeight); if(p_rgb_buffer==NULL) { printf("Allocate memory error!\n"); fclose(fp_in); return -1; } //读取24位色图像数据 fseek(fp_in,file_header.bfOffBits,SEEK_SET); fread(p_rgb_buffer,row_size*info_header.biHeight,1,fp_in); //计算1位色图像每行的字节数 int mono_row_size=(info_header.biWidth+31)/32*4; //分配1位色图像缓冲区 p_mono_buffer=(unsigned char*)malloc(mono_row_size*info_header.biHeight); if(p_mono_buffer==NULL) { printf("Allocate memory error!\n"); fclose(fp_in); free(p_rgb_buffer); return -1; } //将24位色图像数据转换1位色图像数据 for(int i=0;i<info_header.biHeight;i++) { for(int j=0;j<info_header.biWidth;j++) { int index=(i*mono_row_size+j/8); p_mono_buffer[index]|=((p_rgb_buffer[i*row_size+j].rgbtRed>128)?(1<<(7-j%8)):0); } } //将1位色图像数据写入输出文件 FILE *fp_out=fopen(output_file,"wb"); if(fp_out==NULL) { printf("Open output file error!\n"); fclose(fp_in); free(p_rgb_buffer); free(p_mono_buffer); return -1; } fwrite(&file_header,sizeof(BITMAPFILEHEADER),1,fp_out); fwrite(&info_header,sizeof(BITMAPINFOHEADER),1,fp_out); fwrite(p_mono_buffer,mono_row_size*info_header.biHeight,1,fp_out); fclose(fp_in); fclose(fp_out); free(p_rgb_buffer); free(p_mono_buffer); return 0; } ``` 该程序实现了以下功能: 1. 读取24位色位图文件头和信息头信息。 2. 分配24位色图像缓冲区,并读取24位色图像数据。 3. 分配1位色图像缓冲区,将24位色图像数据转换1位色图像数据。 4. 将1位色图像数据写入输出文件。 5. 释放分配的内存,关闭文件句柄
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dvlinker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值