Слияние кода завершено, страница обновится автоматически
#include"bm.h"
BITMAP_PZ CreMap_pz(char* filenmae) //创建位图,从文件读取位图
{
BITMAP_PZ pzbm; //创建临时位图
BITMAPFILEHEADEr bitHead; //位图文件头信息结构定义
BITMAPINFOHEADEr bitInfoHead; //信息头BITMAPINFOHEADER结构
RGBQUAd *pRgb; //调色板
FILE* pfile;
pfile = fopen(filenmae, "rb");//打开文件
if (pfile != NULL)
{
printf("file bkwood.bmp open success.\n");
//读取位图文件头信息
fread(&pzbm.fileType, 1, sizeof(WORD), pfile);
if (pzbm.fileType != 0x4d42) //判断是否为位图文件
{
printf("file is not .bmp file!");
exit(0);
}
//fseek(pfile,2,SEEK_CUR); // "BM"
fread(&pzbm.BitHead, 1, sizeof(BITMAPFILEHEADEr), pfile); //读取位图文件头
//showBmpHead(&bitHead);
//printf("\n\n");
fread(&pzbm.BitInfoHead, 1, sizeof(BITMAPINFOHEADEr), pfile); //读取位图信息头信息
//showBmpInforHead(&bitInfoHead);
//printf("\n");
}
else
{
printf("file open fail!\n");
exit(1);
}
//调色板
if (pzbm.BitInfoHead.biBitCount < 24)//有调色板
{
//读取调色盘结信息
long nPlantNum = long(pow(2, double(pzbm.BitInfoHead.biBitCount))); // Mix color Plant Number;
pRgb = (RGBQUAd *)malloc(nPlantNum*sizeof(RGBQUAd)); //分配一个调色板节点内存
memset(pRgb, 0, nPlantNum*sizeof(RGBQUAd)); //清空
int num = fread(pRgb, 4, nPlantNum, pfile); //在文件中读取一个调色板信息
printf("Color Plate Number: %d\n", nPlantNum);
printf("颜色板信息:\n");
for (int i = 0; i<nPlantNum; i++)
{
if (i % 5 == 0)
{
printf("\n");
}
//showRgbQuan(&pRgb[i]);
}
printf("\n");
}
int width = pzbm.BitInfoHead.biWidth;
int height = pzbm.BitInfoHead.biHeight;
//分配内存空间把源图存入内存
int l_width = WIDTHBYTES(width* pzbm.BitInfoHead.biBitCount);//计算位图的实际宽度并确保它为32的倍数
BYTE *pColorData = (BYTE *)malloc(height*l_width);
memset(pColorData, 0, height*l_width);
long nData = height*l_width;
//把位图数据信息读到数组里
fread(pColorData, 1, nData, pfile);
//将位图数据转化为RGB数据
RGBQUAd* dataOfBmp;
dataOfBmp = (RGBQUAd *)malloc(width*height*sizeof(RGBQUAd));//用于保存各像素对应的RGB数据
memset(dataOfBmp, 0, width*height*sizeof(RGBQUAd));
if (pzbm.BitInfoHead.biBitCount<24)//有调色板,即位图为非真彩色
{
int k;
int index = 0;
if (pzbm.BitInfoHead.biBitCount == 1)
{
for (int i = 0; i<height; i++)
for (int j = 0; j<width; j++)
{
BYTE mixIndex = 0;
k = i*l_width + j / 8;//k:取得该像素颜色数据在实际数据数组中的序号
//j:提取当前像素的颜色的具体值
mixIndex = pColorData[k];
switch (j % 8)
{
case 0:
mixIndex = mixIndex << 7;
mixIndex = mixIndex >> 7;
break;
case 1:
mixIndex = mixIndex << 6;
mixIndex = mixIndex >> 7;
break;
case 2:
mixIndex = mixIndex << 5;
mixIndex = mixIndex >> 7;
break;
case 3:
mixIndex = mixIndex << 4;
mixIndex = mixIndex >> 7;
break;
case 4:
mixIndex = mixIndex << 3;
mixIndex = mixIndex >> 7;
break;
case 5:
mixIndex = mixIndex << 2;
mixIndex = mixIndex >> 7;
break;
case 6:
mixIndex = mixIndex << 1;
mixIndex = mixIndex >> 7;
break;
case 7:
mixIndex = mixIndex >> 7;
break;
}
//将像素数据保存到数组中对应的位置
dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
index++;
}
}
if (pzbm.BitInfoHead.biBitCount == 2)
{
for (int i = 0; i<height; i++)
for (int j = 0; j<width; j++)
{
BYTE mixIndex = 0;
k = i*l_width + j / 4;//k:取得该像素颜色数据在实际数据数组中的序号
//j:提取当前像素的颜色的具体值
mixIndex = pColorData[k];
switch (j % 4)
{
case 0:
mixIndex = mixIndex << 6;
mixIndex = mixIndex >> 6;
break;
case 1:
mixIndex = mixIndex << 4;
mixIndex = mixIndex >> 6;
break;
case 2:
mixIndex = mixIndex << 2;
mixIndex = mixIndex >> 6;
break;
case 3:
mixIndex = mixIndex >> 6;
break;
}
//将像素数据保存到数组中对应的位置
dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
index++;
}
}
if (pzbm.BitInfoHead.biBitCount == 4)
{
for (int i = 0; i<height; i++)
for (int j = 0; j<width; j++)
{
BYTE mixIndex = 0;
k = i*l_width + j / 2;
mixIndex = pColorData[k];
if (j % 2 == 0)
{//低
mixIndex = mixIndex << 4;
mixIndex = mixIndex >> 4;
}
else
{//高
mixIndex = mixIndex >> 4;
}
dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
index++;
}
}
if (pzbm.BitInfoHead.biBitCount == 8)
{
for (int i = 0; i<height; i++)
for (int j = 0; j<width; j++)
{
BYTE mixIndex = 0;
k = i*l_width + j;
mixIndex = pColorData[k];
dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
index++;
}
}
if (pzbm.BitInfoHead.biBitCount == 16)
{
for (int i = 0; i<height; i++)
for (int j = 0; j<width; j++)
{
WORD mixIndex = 0;
k = i*l_width + j * 2;
WORD shortTemp;
shortTemp = pColorData[k + 1];
shortTemp = shortTemp << 8;
mixIndex = pColorData[k] + shortTemp;
dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;
dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen;
dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;
dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;
index++;
}
}
}
else//位图为24位真彩色
{
int k;
int index = 0;
for (int i = 0; i<height; i++)
for (int j = 0; j<width; j++)
{
k = i*l_width + j * 3;
dataOfBmp[index].rgbRed = pColorData[k + 2];
dataOfBmp[index].rgbGreen = pColorData[k + 1];
dataOfBmp[index].rgbBlue = pColorData[k];
index++;
}
}
printf("像素数据信息:\n");
//for (int i=0; i<width*height; i++)
//{
// if (i%5==0)
// {
// printf("\n");
// }
// showRgbQuan(&dataOfBmp[i]);
//}
pzbm.DataOfBmp = dataOfBmp;
if (pzbm.BitInfoHead.biBitCount<24)
{
free(pRgb);
}
free(pColorData);
fclose(pfile); //关闭文件
return pzbm;
}
RGBQUAd GetPix(BITMAP_PZ* bmp, int x, int y) //获得位图上一点的颜色
{
long long kn = bmp->BitInfoHead.biWidth*(bmp->BitInfoHead.biHeight - y-1) + x;
return bmp->DataOfBmp[kn];
}
void CloseBM_pz(BITMAP_PZ bmp) //关闭位图
{
free(bmp.DataOfBmp);
}
int getLineSize(int x1, int y1, int x2, int y2) //得到两点的线段长度
{
return (int)sqrt(pow((double)(x1 - x2), 2) + pow((double)(y1 - y2), 2));
}
static double ex_toRad(double a) //角度转换为弧度
{
return (a*3.14159265f) / 180;
}
//点(x,y)旋转指定弧度r,得到旋转后的坐标
//旋转一条水平线,得到旋转后的坐标
//参数:旋转中心点(px,py),旋转横向半径rx,旋转纵向半径ry, 旋转后坐标指针(*x,*y)
void toSpin(int px, int py, int rx, int ry, int r, int* x, int* y)
{
*x = (int)(px + (rx)*cos(ex_toRad((double)r)));
*y = (int)(py + (ry)*sin(ex_toRad((double)r)));
}
void ToSpin(int px, int py, int rx, int ry, int r, int *x, int *y) //点(x,y)绕(px,py)旋转指定角度r,得到旋转后的点坐标
{
int r1 = r;
double j = (double)r1 * 3.1415926 / 180; //实际弧度
*x = (rx - px)*cos(j) - (ry - py)*sin(j)+ px;
*y = (ry - py)*cos(j)+ (rx - px)*sin(j)+ py;
}
// 返回点(rx,ry)以点(px,py)为圆心逆时针旋转alpha(单位:角度)后所在的位置
//
Ponit Rotate(double px, double py, double alpha, double rx, double ry)
{
Ponit tp;
rx -= px;
ry -= py;
tp.x = rx * cos(ex_toRad(alpha)) - ry * sin(ex_toRad(alpha)) + px;
tp.y = ry * cos(ex_toRad(alpha)) + rx * sin(ex_toRad(alpha)) + py;
return tp;
}
bool isfill(BITMAP_PZ *bmp, int *fi, int x, int y) //判断周围点是否有两个被选
{
int count = 0;
int b[6][2] = { { 1, -1 }, { -1, 1 }, { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
for (int j = 0; j < 6; j++)
{
//if (x + b[j][0] < 0 && (y + b[j][1] < 0) && (x + b[j][0] > bmp->BitInfoHead.biWidth) && (y + b[j][1] > bmp->BitInfoHead.biHeight))
//continue;
if (x + b[j][0] + (y + b[j][1])*bmp->BitInfoHead.biWidth >= 0 &&( x + b[j][0] + (y + b[j][1])*bmp->BitInfoHead.biWidth)<=(bmp->BitInfoHead .biWidth *bmp->BitInfoHead .biHeight) )
if (fi[x + b[j][0] + (y + b[j][1])*bmp->BitInfoHead.biWidth] == 1)
count++;
if (count > 2)
return true;
}
return false;
}
bool shibie(BITMAP_PZ *bmp, int *fill, int x, int y) //识别
{
int num = 0;
int x1, y1;
RGBQUAd rgbb = GetPix(bmp, x, y);
int yuv = rgbb.rgbRed*0.299 + rgbb.rgbGreen*0.578 + rgbb.rgbBlue*0.114;
for (int i = 0; i < 360; i += 20)
{
toSpin(x, y, 5, 5, i, &x1, &y1);
if (x1<0 || y1<0 || x1>=bmp->BitInfoHead.biWidth || y1>=bmp->BitInfoHead.biHeight)
continue;
RGBQUAd rgbb1 = GetPix(bmp, x1, y1);
if (rgbb1.rgbRed*0.299 + rgbb1.rgbGreen*0.578 + rgbb1.rgbBlue*0.114 - yuv>12)
num++;
}
if (num > 10)
{
//if (!isfill(bmp, fill, x, y))
{
fill[x + (y)*bmp->BitInfoHead.biWidth] = 1;
}
return true;
}
else
{
return false;
}
}
/**
void showBmpHead(BITMAPFILEHEADEr* pBmpHead) //显示文件头
{
printf("位图文件头:\n");
printf("文件大小:%d\n", pBmpHead->bfSize);
printf("保留字:%d\n", pBmpHead->bfReserved1);
printf("保留字:%d\n", pBmpHead->bfReserved2);
printf("实际位图数据的偏移字节数:%d\n", pBmpHead->bfOffBits);
}
void showBmpInforHead(BITMAPINFOHEADEr* pBmpInforHead) //显示位图信息头
{
printf("位图信息头:\n");
printf("结构体的长度:%d\n", pBmpInforHead->biSize);
printf("位图宽:%d\n", pBmpInforHead->biWidth);
printf("位图高:%d\n", pBmpInforHead->biHeight);
printf("biPlanes平面数:%d\n", pBmpInforHead->biPlanes);
printf("biBitCount采用颜色位数:%d\n", pBmpInforHead->biBitCount);
printf("压缩方式:%d\n", pBmpInforHead->biCompression);
printf("biSizeImage实际位图数据占用的字节数:%d\n", pBmpInforHead->biSizeImage);
printf("X方向分辨率:%d\n", pBmpInforHead->biXPelsPerMeter);
printf("Y方向分辨率:%d\n", pBmpInforHead->biYPelsPerMeter);
printf("使用的颜色数:%d\n", pBmpInforHead->biClrUsed);
printf("重要颜色数:%d\n", pBmpInforHead->biClrImportant);
}
void showRgbQuan(RGBQUAd* pRGB) //显示调色版信息
{
printf("(%-3d,%-3d,%-3d) ", pRGB->rgbRed, pRGB->rgbGreen, pRGB->rgbBlue);
}
*/
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )