#include<stdio.h>
#include <stdlib.h>
#include<windows.h>
#include<math.h>
#include<wingdi.h>
#pragma pack(1)
void CASE1(char *p);
void CASE2(char *p);
int CASE3();
void CASE4(char *p);
void CASE5();
void CASE6();
void CASE7();
void CASE8();
char* GetFilename(char *p);
void bubblesort(int *buf, int n);
BITMAPFILEHEADER fileHead;
BITMAPINFOHEADER infoHead;
RGBQUAD *pColorTable;
int pColorTableSize = 1024, lineByte;
unsigned char *pBmpBuf, *pBmpBuf1, *p;
FILE *fp, *fp1; // 定义一个文件指针
unsigned char *p1, *p2;
int main()
{
int order = 0;
char dizhi[100] = { 0 }, chucun[100] = { 0 };
printf("*************************************************\n*\tSimple Bitmap Processing System \t*\n*\t\t\tby08A18321 梁炯鹏 \t*\n*\t\t\tby08A18323 严子逊 \t*\n*\t\t\tby08A18324 卢甲浩 \t*\n*\t\t\tby08A18332 苑雨康 \t*\n*************************************************\n");
while (1)
{
printf("\nlast operation:%d", order);
printf("\nCurrent Bitmap File:%s\n", dizhi);
printf("1. Read Bitmap File From File \n2. Print Bitmap File Information \n3. Save Processing Results to File \n4. Display Saved File \n5. Image Processing Algorithm1(水平镜像)\n6.Image Processing Algorithm1(垂直镜像)\n7. Image Processing Algorithm2(马赛克) \n8. Image Processing Algorithm3(bmp图像二值化处理) \n9. Quit \nPlease Choose(1-9): ");
scanf("%d", &order);
switch (order)
{
case 1:
CASE1(dizhi);
break;
case 2:
CASE2(dizhi);
break;
case 3:
CASE3();
break;
case 4:
CASE4(dizhi);
break;
case 5:
CASE5();
break;
case 6:
CASE6();
break;
case 7:
CASE7();
break;
case 8:
CASE8();
break;
case 9:
return 0;
}
}
}
void CASE1(char *p)
{
printf("输入地址: ");
scanf("%s", p);
if ((fp = fopen(p, "rb")) == NULL)
printf("Can't open the file!\n");
else
{
fseek(fp, 0, 0);
fread(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp);
fread(&infoHead, sizeof(BITMAPINFOHEADER), 1, fp);
lineByte = (infoHead.biWidth*infoHead.biBitCount / 8 + 3) / 4 * 4;
pBmpBuf = (unsigned char*)malloc(lineByte*infoHead.biHeight);
pBmpBuf1 = (unsigned char*)malloc(lineByte*infoHead.biHeight);
pColorTable = (RGBQUAD*)malloc(sizeof(RGBQUAD) * 256);
fread(pColorTable, sizeof(RGBQUAD), 256, fp);
fread(pBmpBuf, lineByte*infoHead.biHeight, 1, fp);
fclose(fp);
printf("File open successfully!\n");
}
}
void CASE2(char *p)
{
// int i = sizeof(BITMAPFILEHEADER);
// int j = sizeof(long);
printf("\nFileName\t\t%s \n", GetFilename(p));
printf("FileSize\t\t%d Bytes \n", fileHead.bfSize);
printf("PaletteSize\t\t%d Bytes \n", (int)pow(2, infoHead.biBitCount) * 4);
printf("ImageSize\t\t%d Bytes \n", infoHead.biSizeImage);
printf("Width x Height x Bit\t%d Pixels x %d Pixels x %d Bits \n", infoHead.biWidth, infoHead.biHeight, infoHead.biBitCount);
}
char* GetFilename(char *p) //获得文件名
{
int x = strlen(p);
char ch = '\\';
char *q = strrchr(p, ch);
return q;
}
int CASE3() // 写入文件
{
char *dizhi2[100] = { 0 };
printf("输入地址: ");
scanf("%s", dizhi2);
FILE *fp1 = fopen(dizhi2, "wb");
if (fp1 == 0)
{
printf("Cann't open the file!\n");
return 0;
}
else
{
printf("File written successfully!\n");
}
BITMAPFILEHEADER dstFileHead;
dstFileHead.bfOffBits = 14 + 40 + pColorTableSize;
dstFileHead.bfReserved1 = 0;
dstFileHead.bfReserved2 = 0;
dstFileHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + pColorTableSize + lineByte * infoHead.biHeight;
dstFileHead.bfType = 0x4D42;
fwrite(&dstFileHead, sizeof(dstFileHead), 1, fp1);
BITMAPINFOHEADER dstInfoHead;
dstInfoHead.biBitCount = infoHead.biBitCount;
dstInfoHead.biClrImportant = 0;
dstInfoHead.biClrUsed = 0;
dstInfoHead.biCompression = 0;
dstInfoHead.biHeight = infoHead.biHeight;
dstInfoHead.biPlanes = 1;
dstInfoHead.biSize = 40;
dstInfoHead.biSizeImage = lineByte * infoHead.biHeight;
dstInfoHead.biWidth = infoHead.biWidth;
dstInfoHead.biXPelsPerMeter = 0;
dstInfoHead.biYPelsPerMeter = 0;
fwrite(&dstInfoHead, sizeof(BITMAPINFOHEADER), 1, fp1);
fwrite(pColorTable, sizeof(RGBQUAD), 256, fp1);
fwrite(pBmpBuf1, lineByte*infoHead.biHeight, 1, fp1);
fclose(fp1);
return 0;
}
void CASE4(char *p)
{
ShellExecute(NULL, "open", p, NULL, NULL, SW_SHOW);
}
void CASE5() //水平镜像
{
for (int i = 0; i < infoHead.biHeight; ++i)
{
for (int j = 0; j < infoHead.biWidth; ++j)
{
unsigned char *p1, *p2;
p1 = (unsigned char *)(pBmpBuf + i * lineByte + (infoHead.biWidth - 1 - j));
p2 = (unsigned char *)(pBmpBuf1 + i * lineByte + j);
(*p2) = (*p1);
}
}
printf("horizontal flip completed!\n");
}
void CASE6() //竖直镜像
{
for (int i = 0; i < infoHead.biHeight; ++i)
{
for (int j = 0; j < infoHead.biWidth; ++j)
{
unsigned char *p1, *p2;
p1 = (unsigned char *)(pBmpBuf + (infoHead.biHeight - 1 - i)*lineByte + j);
p2 = (unsigned char *)(pBmpBuf1 + i * lineByte + j);
(*p2) = (*p1);
}
}
printf("vertical flip completed!\n");
}
void CASE7() //马赛克
{
for (int i = 0; i < infoHead.biHeight; i = i + 3)
{
int temp1 = i;
for (int j = 0; j < infoHead.biWidth; j = j + 3) //划分小块
{
int temp2 = j;
int r[9] = { 0 };
int temp = 0;
for (int i = temp1; i < temp1 + 3; ++i) //读3*3小块中数据给入数组
{
for (int j = temp2; j < temp2 + 3; ++j)
{
p = (unsigned char*)(pBmpBuf + i * lineByte + j);
r[temp] = (*p);
temp++;
}
}
bubblesort(r, 9);
for (int i = temp1; i < temp1 + 3; ++i) //把每个小块中的9个像素值全部赋为第四项(中位数)的值
{
for (int j = temp2; j < temp2 + 3; ++j)
{
p = (unsigned char*)(pBmpBuf1 + i * lineByte + j);
(*p) = r[4];
}
}
}
}
printf("mask completed!\n");
}
void CASE8() //bmp图像二值化处理
{
unsigned char *p1, *p2;
int k = 0;
float sum1 = 0.0, sum2 = 0.0;
float temp1 = 0.0, temp2 = 0.0;
float w1 = 0.0, w2 = 0.0;
float u1 = 0.0, u2 = 0.0;
float o1 = 0.0, o2 = 0.0;
float func = 0.0;
float function[256] = { 0.0 };
float N = 0.0;
float n1 = 0.0, n2 = 0.0;
float jz1 = 0.0, jz2 = 0.0;
float fc1 = 0, fc2 = 0;
while (k <= 255)
{
int a[256] = { 0 };
for (int i = 0; i < infoHead.biHeight; i = i + 1)
{
for (int j = 0; j < infoHead.biWidth; j = j + 1)
{
p1 = (unsigned char*)(pBmpBuf + i * lineByte + j);
a[*p1]++; //分别统计不同灰度值的像素个数
}
}
for (int p = 0; p < 256; p++) //求像素点总量
{
N = N + a[p];
}
//概率
for (int p = 0; p <= k; p++)
{
n1 = n1 + a[p];
}
w1 = n1 / N;
for (int p = k + 1; p < 256; p++)
{
n2 = n2 + a[p];
}
w2 = n2 / N;
//均值
for (int p = 0; p <= k; p++)
{
jz1 = jz1 + p * a[p];
}
u1 = jz1 / (N*w1);
for (int p = k + 1; p < 256; p++)
{
jz2 = jz2 + p * a[p];
}
u2 = jz2 / (N*w2);
//方差
for (int p = 0; p <= k; p++)
{
fc1 = fc1 + a[p] * (p - u1)*(p - u1);
}
o1 = fc1 / (N*w1);
for (int p = k + 1; p < 256; p++)
{
fc2 = fc2 + a[p] * (p - u2)*(p - u2);
}
o2 = fc2 / (N*w2);
// 方程
func = w1 * w2*(u1 - u2)*(u1 - u2) / (w1*w2*(u1 - u2)*(u1 - u2) + w1 * o1*o1 + w2 * o2*o2);
function[k] = func;
k++;
}
float max = function[0];
int finalnum = 0;
for (int i = 1; i < 256; i++)
{
if (function[i] > max)
{
max = function[i];
finalnum = i; //找出使函数最大时的灰度值
}
}
printf("使目标函数为最大值的t值为 %d\n", finalnum);
int a[256] = { 0 };
for (int i = 0; i < infoHead.biHeight; i = i + 1)
{
for (int j = 0; j < infoHead.biWidth; j = j + 1)
{
p1 = (unsigned char*)(pBmpBuf + i * lineByte + j);