📄 dib.cpp
字号:
}
LONG DIB::GetHeight()
{
return ((BITMAPINFOHEADER *)m_pDib)->biHeight;
}
//////////////////////光线补偿//////////////////////////////
////////////////////////////////////////////////////////////
BOOL DIB::LightingCompensate(HANDLE hDIB)
{
if(!hDIB)
return FALSE;
LPBITMAPINFOHEADER lpbi;
int width,height;
LPBYTE lpData;
WORD wBytesPerLine;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
//得到图片宽和高
width = lpbi->biWidth;
height = lpbi->biHeight;
//得到图片数据区
lpData = this->FindDIBBits(hDIB);
//得到图片每行的象素所占字节个数
wBytesPerLine = this->BytePerLine(hDIB);
//比例系数
const float thresholdco = 0.05;
//象素个数的临界常数
const int thresholdnum = 100;
//灰度级数组
int histogram[256];
for(int i =0;i<256;i++)
histogram[i] = 0;
//对于过于小的图片的判断
if(width*height*thresholdco < thresholdnum)
return false;
int colorr,colorg,colorb;
long lOffset;
//考察整个图片
for( i=0;i<height;i++)
for(int j=0;j<width;j++)
{
//得到象素数据的偏移
lOffset = this->PixelOffset(i,j,wBytesPerLine);
//得到rgb值
colorb = *(lpData+lOffset++);
colorg = *(lpData+lOffset++);
colorr = *(lpData+lOffset++);
//计算灰度值
int gray = (colorr * 299 + colorg * 587 + colorb * 114)/1000;
histogram[gray]++;
}
int calnum =0;
int total = width*height;
int num;
//下面的循环得到满足系数thresholdco的临界灰度级
for(i =0;i<256;i++)
{
if((float)calnum/total < thresholdco)
{
calnum+= histogram[255-i];
num = i;
}
else
break;
}
int averagegray = 0;
calnum =0;
//得到满足条件的象素总的灰度值
for(i = 255;i>=255-num;i--)
{
averagegray += histogram[i]*i;
calnum += histogram[i];
}
averagegray /=calnum;
//得到光线补偿的系数
float co = 255.0/(float)averagegray;
//下面的循环对图象进行光线补偿
for(i =0;i<height;i++)
for(int j=0;j<width;j++)
{
//得到数据偏移
lOffset = this->PixelOffset(i,j,wBytesPerLine);
//得到蓝色分量
colorb = *(lpData+lOffset);
//调整
colorb *=co;
//临界判断
if(colorb >255)
colorb = 255;
//保存
*(lpData+lOffset) = colorb;
//绿色分量
colorb = *(lpData+lOffset+1);
colorb *=co;
if(colorb >255)
colorb = 255;
*(lpData+lOffset+1) = colorb;
//红色分量
colorb = *(lpData+lOffset+2);
colorb *=co;
if(colorb >255)
colorb = 255;
*(lpData+lOffset+2) = colorb;
}
return TRUE;
}
//////////////////////////////////////膨胀////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void DIB::Dilation(HANDLE hDIB,int m_top,int m_bottom,int m_left,int m_right)
{
LPBITMAPINFOHEADER lpbi;
int height;
int width;
WORD wBytesPerLine;
LPBYTE lpData;
LPBYTE lpTemp;
long lOffset;
//得到图象的基本信息
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
height = m_top;
width = m_right;
wBytesPerLine = this->BytePerLine(hDIB);
lpData = this->FindDIBBits(hDIB);
//申请一块和数据区大小相同的内存
lpTemp = (LPBYTE) new BYTE[wBytesPerLine * height];
long lOffsetJudge;
for (int i=1+m_bottom; i<height-1; i++)
for (int j=1+m_left; j<width-1; j++)
{
lOffset = this->PixelOffset(i, j, wBytesPerLine);
//如果当前点为白色,接着循环
if(*(lpData + lOffset) == 255)
{
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
continue;
}
//否则考察上下左右四个点
else
{
lOffsetJudge = this->PixelOffset(i-1, j, wBytesPerLine);
//如果上面的点为白色
if(*(lpData + lOffsetJudge) == 255)
{ //设置为白色,并继续循环
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
continue;
}
//考察下面的点
lOffsetJudge = this->PixelOffset(i+1,j, wBytesPerLine);
if(*(lpData + lOffsetJudge) == 255)
{
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
continue;
}
//考察左边的点
lOffsetJudge = this->PixelOffset(i,j-1, wBytesPerLine);
if(*(lpData + lOffsetJudge) == 255)
{
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
continue;
}
//考察右边的点
lOffsetJudge = this->PixelOffset(i,j+1, wBytesPerLine);
if(*(lpData + lOffsetJudge) == 255)
{
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
*(lpTemp + lOffset++) = 255;
continue;
}
//如果上下左右都是黑色点,则把暂时区域的点设置为黑色
lOffset = this->PixelOffset(i,j,wBytesPerLine);
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
}
}
//处理图象四周的点,设置为黑色
for(i=m_bottom; i<height; i++)
{
lOffset = this->PixelOffset(i, 0, wBytesPerLine);
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
}
}
for(i=m_bottom; i<height; i++)
{
lOffset = this->PixelOffset(i, width-1, wBytesPerLine);
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
}
}
for(i=m_left; i<width; i++)
{
lOffset = this->PixelOffset(0, i, wBytesPerLine);
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
}
}
for(i=m_left; i<width; i++)
{
lOffset = this->PixelOffset(height-1, i, wBytesPerLine);
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
}
}
//把暂时区域的点拷贝到原句柄区域下面
memcpy(lpData, lpTemp, wBytesPerLine*height);
delete [] lpTemp;
GlobalUnlock(hDIB);
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////腐蚀///////////////////////////////////////
void DIB::Erasion(HANDLE hDIB,int m_top,int m_bottom,int m_left,int m_right)
{
LPBITMAPINFOHEADER lpbi;
LPBYTE lpData;
WORD wBytesPerLine;
long lOffset;
long lOffsetJudge;
int height;
int width;
//得到基本数据
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
height = m_top;
width = m_right;
wBytesPerLine = BytePerLine(hDIB);
lpData = FindDIBBits(hDIB);
HANDLE hTempDIB;
LPBYTE lpTemp;
//申请同样大小的内存
hTempDIB = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER) + wBytesPerLine*height));
//判断内存情况
if(!hTempDIB)
{
GlobalFree(hTempDIB);
GlobalFree(hDIB);
return;
}
lpTemp = (LPBYTE)GlobalLock(hTempDIB);
lpTemp+= sizeof(BITMAPINFOHEADER);
//下面的循环实现腐蚀功能
for (int i=1+m_bottom; i<height-1; i++)
for (int j=1+m_left; j<width-1; j++)
{
lOffset = PixelOffset(i,j,wBytesPerLine);
//如果为白色点
if (*(lpData+lOffset) == 255)
{
//考察上面的点
lOffsetJudge = PixelOffset(i-1, j, wBytesPerLine);
//如果是黑色就把原来的点设置为黑色,并接着循环
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//考察下面的点
lOffsetJudge = PixelOffset(i+1, j, wBytesPerLine);
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//左面的点
lOffsetJudge = PixelOffset(i, j-1, wBytesPerLine);
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//右面的点
lOffsetJudge = PixelOffset(i, j+1, wBytesPerLine);
if (*(lpData + lOffsetJudge) ==0)
{
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
*(lpTemp + lOffset++) = 0;
continue;
}
//如果上下左右四个点都是白色,则设置为白色
lOffset = this->PixelOffset(i, j, wBytesPerLine);
*(lpTemp + lOffset) = 255;
*(lpTemp + lOffset+1) = 255;
*(lpTemp + lOffset+2) = 255;
}
//如果当前点为黑色,则在暂时的目标区域中设置为黑色
else
{
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
}
//把图象周边的点全部设置为黑色
for(i=m_bottom; i<height; i++)
{
lOffset = PixelOffset(i, 0, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
for(i=m_bottom; i<height; i++)
{
lOffset = PixelOffset(i, width-1, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
for (i=m_left; i<width; i++)
{
lOffset = PixelOffset(0, i, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
for (i=m_left; i<width; i++)
{
lOffset = PixelOffset(height-1, i, wBytesPerLine);
*(lpTemp + lOffset) = 0;
*(lpTemp + lOffset+1) = 0;
*(lpTemp + lOffset+2) = 0;
}
//把暂时区域的数值拷贝到原来的句柄下面
memcpy(lpData,lpTemp,wBytesPerLine*height);
GlobalUnlock(hDIB);
GlobalUnlock(hTempDIB);
GlobalFree(hTempDIB);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -