📄 bmp_info.cpp
字号:
#include "bmp_info.h"
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
/* 消除指针转换的警告 */
#pragma warning(disable:4311)
/* 消除无符号有符号警告 */
#pragma warning(disable:4389)
/* 消除"局部变量可能尚未初始化即被使用"的警告 */
#pragma warning(disable:4701)
BOOL bmp_init(bmp_info *bmp)
{
if(bmp == NULL)
return 1;
bmp->raw_buf = NULL;
bmp->data = NULL;
bmp->width = 0;
bmp->height = 0;
bmp->byte_size = 0;
return 0;
}
BOOL bmp_create(bmp_info *bmp, unsigned int width, unsigned int height)
{
/* 如果原来的大小与要创建的大小相同,则不用分配 */
if( bmp->data &&
width == bmp->width &&
height == bmp->height )
return 0;
bmp_destroy(bmp);
bmp->raw_buf = (BYTE*)malloc(width * height * sizeof(pixel_color) + 16);
if( bmp->raw_buf )
{
/* 数据对齐 */
bmp->data = (pixel_color *)( bmp->raw_buf + 16 - (((int)bmp->raw_buf)%16) );//16 byte align
bmp->width = width;
bmp->height = height;
bmp->byte_size = bmp->width * bmp->height * 4;
}
else
{
bmp->data = NULL;
return 1;
}
return 0;
}
void bmp_destroy(bmp_info *bmp)
{
if(bmp->raw_buf)
{
free(bmp->raw_buf);
bmp->raw_buf = NULL;
bmp->data = NULL;
}
}
BOOL bmp_load_from_file(bmp_info *bmp, char* file_name)
{
unsigned char BGR[1024];
unsigned char ch[2];
DWORD bfSize;
DWORD bfReserved1;
DWORD bfOffBits;
DWORD biSize;
int biWidth;
int biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
DWORD biXPelsPreMeter[2];
DWORD biClrUsed[2];
int indexNumber;
FILE *fp = fopen(file_name,"rb");
/* 如果文件读取失败,则返回 */
if(fp == NULL)
return 1;
fread(&ch,2,1,fp);
/* 判断是否是位图 */
if(ch[0]!='B')
{
fclose(fp);
return 1;
}
/* 读取文件头,位图信息头 */
fread(&bfSize,4,1,fp);
fread(&bfReserved1,4,1,fp);
fread(&bfOffBits,4,1,fp);
fread(&biSize,4,1,fp);
fread(&biWidth,4,1,fp);
fread(&biHeight,4,1,fp);
fread(&biPlanes,2,1,fp);
fread(&biBitCount,2,1,fp);
fread(&biCompression,4,1,fp);
fread(&biSizeImage,4,1,fp);
fread(&biXPelsPreMeter,8,1,fp);
fread(&biClrUsed,8,1,fp);
switch(biBitCount)
{
case 1:
indexNumber=2;
break;
case 4:
indexNumber=16;
break;
case 8:
indexNumber=256;
break;
default:
indexNumber = 0;
break;
}
if(biBitCount!=24)
{
fread(BGR,indexNumber*4,1,fp);
}
/* 读取文件数据 */
unsigned char *buffer;
int width;
int offset;
unsigned char temp;
unsigned char one = 1;
switch(biBitCount)
{
case 1: /* 对于2色图片 */
if(biWidth/32*32!=biWidth)
width=(biWidth/32+1)*4;
else
width=biWidth/8;
break;
case 4: /* 对于16色图片 */
if(biWidth/8*8!=biWidth)
width=(biWidth/8+1)*4;
else
width=biWidth/2;
break;
case 8: /* 对于256色图片 */
if(biWidth/4*4!=biWidth)
width=(biWidth/4+1)*4;
else
width=biWidth;
break;
case 24: /* 对于24位图片 */
if((biWidth*3)/4*4!=biWidth*3)
width=((3*biWidth)/4+1)*4;
else
width=3*biWidth;
break;
default:
fclose(fp);
return 1;
break;
}
buffer = (unsigned char*)malloc(width * sizeof(unsigned char));
if(buffer==NULL)
return 1;
int nRet=bmp_create(bmp, biWidth, biHeight);
if(nRet)
return 1;
BYTE *pData=(BYTE *)bmp_get_buffer_at(bmp, 0, 0);
int i;
int j;
int k;
/* 读取文件图像数据到类中 */
switch(biBitCount)
{
case 1:
for(i=0; i<biHeight; i++)
{
if( fread(buffer,1,width,fp) != width )
return 1;
for(j=0; j<biWidth; j++)
{
offset=(i*biWidth+j)*4;
if(j%8==0)
{
one=128;
temp=buffer[j/8];
}
if((temp&one)==one)
k=4;
else
k=0;
pData[offset]=BGR[k];
pData[offset+1]=BGR[k+1];
pData[offset+2]=BGR[k+2];
one=one>>1;
}
}
break;
case 4:
for(i=0;i<biHeight;i++)
{
if(fread(buffer,1,width,fp)!=width)
return 1;
for(j=0;j<biWidth;j++)
{
offset=(i*biWidth+j)*4;;
if(j%2==0)
{
one=128+64+32+16;
temp=buffer[j/2];
}
k=temp&one;
if(j%2==0)
k=k>>4;
k*=4;
pData[offset]=BGR[k];
pData[offset+1]=BGR[k+1];
pData[offset+2]=BGR[k+2];
one=one>>4;
}
}
break;
case 8:
for(i=0;i<biHeight;i++)
{
if(fread(buffer,1,width,fp)!=width)
return 1;
for(j=0;j<biWidth;j++)
{
offset=(i*biWidth+j)*4;;
k=buffer[j]*4;
pData[offset]=BGR[k];
pData[offset+1]=BGR[k+1];
pData[offset+2]=BGR[k+2];
}
}
break;
case 24:
for(i=0;i<biHeight;i++)
{
if(fread(buffer,1,width,fp)!=width)
return 1;
offset=i*biWidth*4;
for(j=0;j<biWidth;j++)
{
pData[offset+j*4]=buffer[j*3];
pData[offset+j*4+1]=buffer[j*3+1];
pData[offset+j*4+2]=buffer[j*3+2];
}
}
break;
default:
break;
}
if(buffer)
free(buffer);
fclose(fp);
return 0;
}
BOOL bmp_save_to_file(bmp_info *bmp, char* file_name )
{
/* bmp文件头 */
unsigned char header[2];
DWORD bfSize;
DWORD bfReserved1;
DWORD bfReserved2;
DWORD bfOffBits;
DWORD biSize;
int biWidth;
int biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
DWORD biXPelsPreMeter;
DWORD biYPelsPreMeter;
DWORD biClrUsed;
int width;
biWidth=bmp->width;
biHeight=bmp->height;
/* 计算每行所用的字节数 */
if((biWidth*3)/4*4!=biWidth*3)
width=((3*biWidth)/4+1)*4;
else
width=3*biWidth;
/* 义参数 (保存为24位位图) */
header[0]='B';
header[1]='M';
bfReserved1=bfReserved2=0;
bfSize=width*biHeight*3+54;
biSize=40;
bfOffBits=54;
biPlanes=1;
biBitCount=24;
biCompression=0;
biSizeImage=width*biHeight*3;
biXPelsPreMeter=4730;
biYPelsPreMeter=4720;
biClrUsed=0;
/* 保存 */
FILE *fp = fopen(file_name,"wb");
if(fp == NULL)
return 1;
int i,j,offset;
unsigned char *buffer;
/* 存文件头 */
fwrite(&header,1,2,fp);
bfSize=width*biHeight*3+54;
fwrite(&bfSize,1,4,fp);
fwrite(&bfReserved1,1,4,fp);
bfOffBits=54;
fwrite(&bfOffBits,1,4,fp);
fwrite(&biSize,1,4,fp);
/* 存位图信息头 */
fwrite(&biWidth,1,4,fp);
fwrite(&biHeight,1,4,fp);
fwrite(&biPlanes,1,2,fp);
biBitCount=24;
fwrite(&biBitCount,1,2,fp);
fwrite(&biCompression,1,4,fp);
biSizeImage=width*biHeight*3;
fwrite(&biSizeImage,1,4,fp);
fwrite(&biXPelsPreMeter,1,8,fp);
fwrite(&biClrUsed,1,8,fp);
fseek(fp,54,0);
/* 存文件数据 */
BYTE *pData=(BYTE *)bmp_get_buffer_at(bmp, 0, 0);
buffer = (unsigned char*)malloc(sizeof(unsigned char)*width);
for(i=0;i<biHeight;i++)
{
offset=i*biWidth*4;
for(j=0;j<biWidth;j++)
{
buffer[j*3]=pData[offset+j*4];
buffer[j*3+1]=pData[offset+j*4+1];
buffer[j*3+2]=pData[offset+j*4+2];
}
if(fwrite(buffer,1,width,fp)!=width)
return 1;
}
fclose(fp);
if(buffer)
free(buffer);
return 0;
}
pixel_color* bmp_get_buffer_at(bmp_info*bmp, int x,int y)
{
return bmp->data + (y*bmp->width+x);
}
#pragma warning(default:4311)
#pragma warning(default:4389)
#pragma warning(default:4701)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -