#include <stdio.h>
#include <Windows.h>
//
/***********************************************
功能: 读位图文件
参数: char * 为位图文件的路径
****************************************************/
int readBmp(char *);
/*********************************************************************************************************
功能: 保存位图
参数: char *bmpPath 位图的路径(或文件名)
char *pImgBuf 位图的数据
int bmpWidth 位图的宽,以像素为单位
int bmpHeight 位图的高,以像素为单位
int biBitCount位图每个像素占的字节数
RGBQUAD *pColorTable位图的颜色表
***********************************************************************************************************/
int saveBmp(char *bmpPath,unsigned char *pImgBuf, int bmpWidth, int bmpHeight, int biBitCount, RGBQUAD *pColorTable);
/***************************************************************
功能: 将图像数据左下角1/4部分置成黑色
参数: unsigned char *pImgData 图像数据
int biWidth 图像的宽,以像素为单位
int biHeight 图像的高,以像素为单位
int biBitCount 图像的每个像素占的位数
返回值:return 0; 失败返回0
return 1; 成功返回1
*****************************************************************/
int changeLeftBottomToBlack(unsigned char *pImgData,int biWidth,int biHeight, int biBitCount);
unsigned char *gpImgBuf; //保存位图数据
RGBQUAD *gpColorTable; //颜色表指针
int gwidth; //保存位图的宽,以像素为单位
int gheight; //保存位图的高,以像素为单位
int gbiBitCount; //位图的每个像素占的位数(即占几个bit)
void main()
{
char bmpPath[] = "dog.bmp";
if (!readBmp(bmpPath))
return;
//changeLeftBottomToBlack(gpImgBuf, gwidth, gheight, gbiBitCount);
if (!saveBmp("dogcpy.bmp", gpImgBuf, gwidth, gheight, gbiBitCount, gpColorTable))
{
MessageBox(NULL, "保存文件失败", "提示", MB_OK);
}
if (8 == gbiBitCount)
delete[]gpColorTable;
delete[]gpImgBuf;
}
int readBmp(char *bmpPath)
{
//1以二进制读方式打开文件
FILE *fp;
errno_t err;
// Open for read (will fail if file "crt_fopen_s.c" does not exist)
err = fopen_s(&fp, bmpPath, "rb");
if (err == 0)
{
printf("The file 'crt_fopen_s.c' was opened\n");
}
else
{
printf("The file 'crt_fopen_s.c' was not opened\n");
}
//跳过文件头,因为其包含的信息,读出来对我们没有意义
fseek(fp, sizeof(BITMAPFILEHEADER), SEEK_CUR);
//定义位图信息头
BITMAPINFOHEADER infoHeader;
fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
gwidth = infoHeader.biWidth;
gheight = infoHeader.biHeight;
gbiBitCount = infoHeader.biBitCount;
//如果是灰度图像,读取颜色表
if (8 == infoHeader.biBitCount)
{
gpColorTable = new RGBQUAD[256];
fread(gpColorTable, sizeof(RGBQUAD), 256, fp);
}
//计算位图中每行像素所占的字节数(必须是4个字节的整数倍)
int lineByte = (gbiBitCount*gwidth / 8 + 3) / 4 * 4;
gpImgBuf = new unsigned char[lineByte*gheight];
//读取位图数据
fread(gpImgBuf, 1, lineByte*gheight, fp);
if (fclose(fp) != 0)
{
MessageBox(NULL, "读取文件时关闭文件失败", "提示", MB_OK);
return 0;
}
//返回1代表成功读取文件
return 1;
}
int saveBmp(char *bmpPath,unsigned char *pImgBuf, int bmpWidth, int bmpHeight, int biBitCount, RGBQUAD *pColorTable)
{
FILE *fp;
errno_t err;
// Open for write
err = fopen_s(&fp, bmpPath, "wb");
if (err == 0)
{
printf("The file 'data2' was opened\n");
}
else
{
printf("The file 'data2' was not opened\n");
}
//求出颜色表的长度,以字节为单位
int colorTableSize = 0;
if (8 == biBitCount)
{
colorTableSize = 1024;
}
//求出每行像素所占的字节数(必须为4个字节的整数倍)
int lineByte = (biBitCount*bmpWidth / 8 + 3) / 4 * 4;
//初始化位图文件头对象
BITMAPFILEHEADER fileHeader;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = 54 + colorTableSize;
fileHeader.bfSize = 54 + colorTableSize + lineByte*bmpHeight;//strlen(pImgBuf);
fileHeader.bfType = 0x4D42;
//初始化位图信息头对象
BITMAPINFOHEADER infoHeader;
infoHeader.biBitCount = biBitCount;
infoHeader.biClrImportant = 0;
infoHeader.biClrUsed = 0;
infoHeader.biCompression = BI_RGB;
infoHeader.biHeight = bmpHeight;
infoHeader.biPlanes = 1;
infoHeader.biSize = 40;
infoHeader.biSizeImage = 0;
infoHeader.biWidth = bmpWidth;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
//写位图文件头和位图信息头
fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
//写颜色表
if (8 == biBitCount)
{
fwrite(pColorTable, colorTableSize, 1, fp);
}
fwrite(pImgBuf, 1, lineByte*bmpHeight, fp);
if (fclose(fp) != 0)
{
MessageBox(NULL, "写入文件时关闭文件失败", "提示", MB_OK);
//返回0表示以写方式写入位图失败
return 0;
}
//返回1表示成功保存位图
return 1;
}
int changeLeftBottomToBlack(unsigned char *pImgData, int biWidth, int biHeight,int biBitCount)
{
if (pImgData == NULL)
return 0;
//For uncompressed RGB bitmaps, if biHeight is positive, the bitmap is a bottom - up DIB with the origin at the lower left corner.
if (biHeight > 0)
{
//计算每行像素占的字节数
int lineByte = (biWidth*biBitCount / 8 + 3) / 4 * 4;
//灰度图像
if (8 == biBitCount)
{
for (int i = 0; i < (biHeight / 2); i++)
{
for (int j = 0; j < (biWidth / 2); j++)
{
*(pImgData + i*lineByte + j) = 0;
}
}
return 1;
}
//彩色图像
for (int i = 0; i < biHeight / 2; i++)
{
for (int j = 0; j < biWidth / 2; j++)
{
*(pImgData + i*lineByte + j * 3) = 0;//B
*(pImgData + i*lineByte + j * 3 + 1) = 0;//G
*(pImgData + i*lineByte + j * 3 + 2) = 0;//R
}
}
//
return 1;
}
//If biHeight is negative, the bitmap is a top - down DIB with the origin at the upper left corner
else
{
::MessageBox(NULL, "the case of the biHeight is negative is not implemeted", "warning", MB_OK);
}
}
评论0