📄 cutbmp.cpp
字号:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
extern HWND hWndMain;
#define DUNIT2LONG(word) ((long)(word[1] << 16 | word[0])) /* 双字节转成长整型 */
typedef unsigned char byte;
typedef unsigned short unit;
/* BMP文件头 */
typedef struct BmpFileHeader
{
unit bfType; /* 位图文件的类型,为BM */
unit bfSize[2]; /* 位图文件的大小,以字节为单位 */
unit bfReserved1; /* 位图文件保留字为0 */
unit bfReserved2; /* 位图文件保留字为0 */
unit bfOffBits[2]; /* 位图数据的起始位置 */
}BMPFILEHEADER;
/* 位图信息头 */
typedef struct BmpInfoHeader
{
unit biSize[2]; /* 本结构所占用字节 */
long biWidth; /* 位图的宽度,像素 */
long biHeight; /* 位图的高度,像素 */
unit biPlanes; /* 目标设备的级别为1*/
unit biBitCount; /* 每个像素位数 */
unit biCompression[2]; /* 位图压缩类型 */
unit biSizeImage[2]; /* 位图的大小 字节 */
long biXPelsPerMeter; /* 位图水平分辨率,每米像素数 */
long biYPelsPerMeter; /* 位图垂直分辨率,每米像素数 */
unit biClrUsed[2]; /* 位图实际使用的颜色表中的颜色数 */
unit biClrImportant[2]; /* 位图显示过程中重要的颜色数 */
}BMPINFOHEADER;
/* 创建位图文件头和位图信息头 */
void CreateHeader(BMPFILEHEADER bf1, BMPINFOHEADER bi1,
BMPFILEHEADER *bf2, BMPINFOHEADER *bi2,
long width, long height)
{
long bfSize = 0, biSize = 0;
memset(bf2, 0x00, sizeof(BMPFILEHEADER));
memset(bi2, 0x00, sizeof(BMPINFOHEADER));
memcpy(bf2, &bf1, sizeof(BMPFILEHEADER));
memcpy(bi2, &bi1, sizeof(BMPINFOHEADER));
biSize = ((((width * bi1.biBitCount) + 0x1f) & ~0x1f) / 8) * height + 2;
bfSize = biSize + DUNIT2LONG(bf1.bfOffBits);
/* 位图文件大小 */
bf2->bfSize[0] = (unit)(bfSize & 0x0000ffff); /* 低位双字节 */
bf2->bfSize[1] = (unit)(bfSize >> 16); /* 高位双字节 */
/* 位图数据大小 */
bi2->biSizeImage[0] = (unit)(biSize & 0x0000ffff); /* 低位双字节 */
bi2->biSizeImage[1] = (unit)(biSize >> 16); /* 高位双字节 */
/* 位图宽和高 */
bi2->biWidth = width;
bi2->biHeight = height;
}
/* 创建单个的剪切的位图 */
int CreateCutFile(char *s, byte *buffer, int cx, int cy, int x, int y)
{
FILE *fp = NULL;
char fName[256], errMsg[256];
long clrSize = 0, headSize = 0, row = 0, line = 0;
long i = 0, j = 0, lineSize = 0, offset = 0,width = 0, height = 0;
byte *p = NULL;
byte tail[4] = {0x00, 0x00, 0x00, 0x00};
BMPFILEHEADER bf, bf1;
BMPINFOHEADER bi, bi1;
memset(&bf, 0x00, sizeof(bf));
memset(&bi, 0x00, sizeof(bi));
memset(fName, 0x00, sizeof(fName));
sprintf(fName, "%s_%d_%d.bmp", s, x, y);
memcpy(&bf, buffer, sizeof(bf));
memcpy(&bi, buffer+sizeof(bf), sizeof(bi));
headSize = sizeof(BMPFILEHEADER) + sizeof(BMPINFOHEADER);
clrSize = DUNIT2LONG(bf.bfOffBits) - headSize;
p = buffer + DUNIT2LONG(bf.bfOffBits);
width = bi.biWidth/cy;
height = bi.biHeight/cx;
CreateHeader(bf, bi, &bf1, &bi1, width, height);
line = bi.biHeight;
row = (((bi.biWidth * bi.biBitCount) + 0x1f) & ~0x1f)/8;
offset = width * bi.biBitCount/8;
lineSize = (((width * bi.biBitCount) + 0x1f) & ~0x1f)/8;
if(NULL == (fp = fopen(fName, "wb")))
{
memset(errMsg, 0x00, sizeof(errMsg));
sprintf(errMsg, "打开文件[%s]出错", fName);
MessageBox(hWndMain, errMsg, "错误", MB_OK);
return -1;
}
fwrite(&bf1, sizeof(bf1), 1, fp); /* 写文件头 */
fwrite(&bi1, sizeof(bi1), 1, fp); /* 写信息头 */
fwrite(buffer + headSize, clrSize, 1, fp); /* 写颜色信息 */
/* 写位图数据,位图采用从左到右从下到上的扫描顺序,行字节数必须为4倍数,不足补0 */
for(i = height-1; i >= 0; i --)
{
fwrite(&p[(line-1-x*height-i)*row + y*offset], offset, 1, fp);
fwrite(tail, sizeof(byte), lineSize - offset, fp);
}
fwrite(tail, sizeof(byte), 2, fp); /* 结尾写两个字节0 */
fclose(fp);
return 0;
}
/* 剪切位图成cx*cy块 */
int CutBmpFile(char *bmpName, char *s, int cx, int cy)
{
struct stat tfile;
char errMsg[256];
FILE *fp = NULL;
long i = 0, j = 0;
byte *buffer = NULL;
BMPFILEHEADER bf;
memset(&tfile, 0x00, sizeof(struct stat));
memset(&bf, 0x00, sizeof(BMPFILEHEADER));
if(-1 == stat(bmpName, &tfile))
{
memset(errMsg, 0x00, sizeof(errMsg));
sprintf(errMsg, "查找文件[%s]信息出错", bmpName);
MessageBox(hWndMain, errMsg, "错误", MB_OK);
return -1;
}
buffer = (byte *)malloc(tfile.st_size + 256);
if(NULL == buffer)
{
MessageBox(hWndMain, "分配内存失败", "错误", MB_OK);
return -1;
}
memset(buffer, 0x00, tfile.st_size + 256);
if(NULL == (fp = fopen(bmpName, "rb")))
{
free(buffer);
memset(errMsg, 0x00, sizeof(errMsg));
sprintf(errMsg, "打开文件[%s]出错", bmpName);
MessageBox(hWndMain, errMsg, "错误", MB_OK);
return -1;
}
fread(buffer, tfile.st_size, 1, fp);
fclose(fp);
memcpy(&bf, buffer, sizeof(BMPFILEHEADER));
if((byte)(bf.bfType & 0x00ff) != 'B' || (byte)(bf.bfType >> 8) != 'M')
{
free(buffer);
MessageBox(hWndMain, "错误BMP图片类型", "错误", MB_OK);
return -1;
}
for(i = 0; i < cx; i ++)
{
for(j = 0; j < cy; j ++)
{
if(CreateCutFile(s, buffer, cx, cy, i, j) < 0)
return -1;
}
}
free(buffer);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -