📄 dib.cpp
字号:
long lOffset;
lOffset = this->PixelOffset(CurrentPoint.y,CurrentPoint.x,wBytesPerLine);
if(*(lpDIBBits+lOffset)!=0)
return false;
if(CurrentPoint.y!=0)
{
lOffset = this->PixelOffset(CurrentPoint.y-1,CurrentPoint.x,wBytesPerLine);
if(*(lpDIBBits+lOffset)==255)
return true;
}
if(CurrentPoint.x!=this->width-1)
{
lOffset = this->PixelOffset(CurrentPoint.y,CurrentPoint.x+1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==255)
return true;
}
if(CurrentPoint.y!=this->height-1)
{
lOffset = this->PixelOffset(CurrentPoint.y+1,CurrentPoint.x,wBytesPerLine);
if(*(lpDIBBits+lOffset)==255)
return true;
}
if(CurrentPoint.x!=0)
{
lOffset = this->PixelOffset(CurrentPoint.y,CurrentPoint.x-1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==255)
return true;
}
return false;
}
CPoint DIB::SearchInteriorPoint(CPoint Point,LPBYTE lpDIBBits,WORD wBytesPerLine)
{
long lOffset;
CPoint Pointtmp;
Pointtmp.x=Pointtmp.y=-1;
if((Point.x!=0)&&(Point.y!=this->height-1))
{
lOffset = this->PixelOffset(Point.y+1,Point.x-1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
{
Pointtmp.x=Point.x-1;
Pointtmp.y=Point.y+1;
return Pointtmp;
}
}
if(Point.y!=this->height-1)
{
lOffset = this->PixelOffset(Point.y+1,Point.x,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
{
Pointtmp.x=Point.x;
Pointtmp.y=Point.y+1;
return Pointtmp;
}
}
if((Point.x!=this->width-1)&&(Point.y!=this->height-1))
{
lOffset = this->PixelOffset(Point.y+1,Point.x+1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
{
Pointtmp.x=Point.x+1;
Pointtmp.y=Point.y+1;
return Pointtmp;
}
}
if(Point.x!=this->width-1)
{
lOffset=this->PixelOffset(Point.y,Point.x+1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
{
Pointtmp.x=Point.x+1;
Pointtmp.y=Point.y;
return Pointtmp;
}
}
return Pointtmp;
}
//对图片中的图形进行细化操作
void DIB::ThinningDIB(HANDLE hDIB)
{
LPBITMAPINFOHEADER lpbi;
WORD wBytesPerLine;
LPBYTE lpDIBBits;
long lOffset;
int width,height;
//细化查询表
static int erasetable[256]={
0,0,1,1,0,0,1,1,
1,1,0,1,1,1,0,1,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,1,
0,0,1,1,0,0,1,1,
1,1,0,1,1,1,0,1,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,1,
1,1,0,0,1,1,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
1,1,0,0,1,1,0,0,
1,1,0,1,1,1,0,1,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,1,1,0,0,1,1,
1,1,0,1,1,1,0,1,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,1,
0,0,1,1,0,0,1,1,
1,1,0,1,1,1,0,1,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,0,
1,1,0,0,1,1,0,0,
0,0,0,0,0,0,0,0,
1,1,0,0,1,1,1,1,
0,0,0,0,0,0,0,0,
1,1,0,0,1,1,0,0,
1,1,0,1,1,1,0,0,
1,1,0,0,1,1,1,0,
1,1,0,0,1,0,0,0
};
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
//得到图片的长宽信息
width = lpbi->biWidth;
height = lpbi->biHeight;
lpDIBBits = this->FindDIBBits(hDIB);
wBytesPerLine = this->BytePerLine(hDIB);
//执行细化,直到没有点可以被去掉为止
int end =0;
while(!end)
{
end =1;
//扫描整个图片,从上往下
for(int i=1;i<height-1;i++)
for(int j=1;j<width-1;j++)
{
//判定当前点的颜色
lOffset = this->PixelOffset(i,j,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
continue;//如果是黑色的,直接考虑下一个点
else
{
int colorleft,colorright;
lOffset =this->PixelOffset(i,j-1,wBytesPerLine);
colorleft = *(lpDIBBits+lOffset);
lOffset = this->PixelOffset(i,j+1,wBytesPerLine);
colorright = *(lpDIBBits+lOffset);
//如果当前点的的左边和右边的点的颜色都是白色
if((colorleft==255)&&(colorright==255))
continue;//直接进行下一个点的处理
else
{
//下面的一段代码考察当前点的周围八个方向上的点的颜色
//并根据颜色设置标志位
int k1,k2,k3,k4,k5,k6,k7,k8;
//左下
lOffset = this->PixelOffset(i+1,j-1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k1=1;
else
k1 =0;
//正下
lOffset = this->PixelOffset(i+1,j,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k2=1;
else
k2 =0;
//右下
lOffset = this->PixelOffset(i+1,j+1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k3=1;
else
k3 =0;
//正左
lOffset = this->PixelOffset(i,j-1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k4=1;
else
k4 =0;
//正右
lOffset = this->PixelOffset(i,j+1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k5=1;
else
k5 =0;
//左上
lOffset = this->PixelOffset(i-1,j-1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k6=1;
else
k6 =0;
//正上
lOffset = this->PixelOffset(i-1,j,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k7=1;
else
k7 =0;
//右上
lOffset = this->PixelOffset(i-1,j+1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k8=1;
else
k8 =0;
int judge;
//计算得到细化查询表中的位置
judge = k1+k2*2+k3*4+k4*8+k5*16+k6*32+k7*64+k8*128;
if(erasetable[judge]==1)
{ //删除
lOffset = this->PixelOffset(i,j,wBytesPerLine);
*(lpDIBBits+lOffset++)=0;
*(lpDIBBits+lOffset++)=0;
*(lpDIBBits+lOffset++)=0;
j++;
end =0;//继续循环
}
}
}
}
//扫描整个图片,从左到右,代码类似
for(int j=1;j<width-1;j++)
for(int i=1;i<height-1;i++)
{
lOffset = this->PixelOffset(i,j,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
continue;
else
{
int colorleft,colorright;
lOffset =this->PixelOffset(i,j-1,wBytesPerLine);
colorleft = *(lpDIBBits+lOffset);
lOffset = this->PixelOffset(i,j+1,wBytesPerLine);
colorright = *(lpDIBBits+lOffset);
if((colorleft==255)&&(colorright==255))
continue;
else
{
int k1,k2,k3,k4,k5,k6,k7,k8;
lOffset = this->PixelOffset(i+1,j-1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k1=1;
else
k1 =0;
lOffset = this->PixelOffset(i+1,j,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k2=1;
else
k2 =0;
lOffset = this->PixelOffset(i+1,j+1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k3=1;
else
k3 =0;
lOffset = this->PixelOffset(i,j-1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k4=1;
else
k4 =0;
lOffset = this->PixelOffset(i,j+1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k5=1;
else
k5 =0;
lOffset = this->PixelOffset(i-1,j-1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k6=1;
else
k6 =0;
lOffset = this->PixelOffset(i-1,j,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k7=1;
else
k7 =0;
lOffset = this->PixelOffset(i-1,j+1,wBytesPerLine);
if(*(lpDIBBits+lOffset)==0)
k8=1;
else
k8 =0;
int judge;
judge = k1+k2*2+k3*4+k4*8+k5*16+k6*32+k7*64+k8*128;
if(erasetable[judge]==1)
{
lOffset = this->PixelOffset(i,j,wBytesPerLine);
*(lpDIBBits+lOffset++)=0;
*(lpDIBBits+lOffset++)=0;
*(lpDIBBits+lOffset++)=0;
j++;
end =0;
}
}
}
}
}
}
BOOL DIB:: SaveDIB(HANDLE hDib, CFile& file)
{
// Bitmap文件头
BITMAPFILEHEADER bmfHdr;
// 指向BITMAPINFOHEADER的指针
LPBITMAPINFOHEADER lpBI;
// DIB大小
DWORD dwDIBSize =0;
if (hDib == NULL)
{
// 如果DIB为空,返回FALSE
return FALSE;
}
// 读取BITMAPINFO结构,并锁定
lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
if (lpBI == NULL)
{
// 为空,返回FALSE
return FALSE;
}
// 判断是否是WIN3.0 DIB
// if (!IS_WIN30_DIB(lpBI))
// {
// 不支持其它类型的DIB保存
// 解除锁定
// ::GlobalUnlock((HGLOBAL) hDib);
// 返回FALSE
// return FALSE;
// }
// 填充文件头
// 文件类型"BM"
bmfHdr.bfType = 0x4d42; //DIB_HEADER_MARKER;
// 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并
// 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。
// 文件头大小+颜色表大小
// (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
// dwDIBSize = *(LPDWORD)lpBI; //+ ::PaletteSize((LPSTR)lpBI);
dwDIBSize = sizeof(BITMAPINFOHEADER);//+lpBI->biSizeImage;
// 计算图像大小
if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
{
// 对于RLE位图,没法计算大小,只能信任biSizeImage内的值
dwDIBSize += lpBI->biSizeImage;
}
else
{
// 象素的大小
DWORD dwBmBitsSize;
// 大小为Width * Height
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*24) * lpBI->biHeight;
// 计算出DIB真正的大小
dwDIBSize += dwBmBitsSize;
// 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
lpBI->biSizeImage = dwBmBitsSize;
}
// 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
// 两个保留字
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize;
// + PaletteSize((LPSTR)lpBI);
// 尝试写文件
// TRY
{
// 写文件头
file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
// 写DIB头和象素
file.WriteHuge(lpBI, dwDIBSize);
}
// CATCH (CFileException, e)
// {
// 解除锁定
// ::GlobalUnlock((HGLOBAL) hDib);
// 抛出异常
/// THROW_LAST();
// }
// END_CATCH
// 解除锁定
::GlobalUnlock((HGLOBAL) hDib);
// 返回TRUE
return TRUE;
}
HANDLE DIB::ScaleDIB(HANDLE hDIB, float scal_x, float scal_y)
{
if(scal_x<0 || scal_y <0)
return NULL;
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
int w = lpbi->biWidth;
int h = lpbi->biHeight;
BYTE tempmess[40];
LPBYTE Src = this->FindDIBBits(hDIB);
memcpy(tempmess,(LPBYTE)lpbi,40);
int wid = ((int)(w*scal_x+0.5f)*24+31)/32*4;
int imgsize =(int) (wid*(int)(h*scal_y+0.5f));
HDIB hDIB2 = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)+imgsize));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB2);
memcpy((LPBYTE)lpbi,tempmess,40);
lpbi->biWidth =(int)(w*scal_x+0.5f);
lpbi->biHeight = (int)(h*scal_y+0.5f);
lpbi->biSizeImage = imgsize;
LPBYTE lpData = this->FindDIBBits(hDIB2);
int srcWidth = w;
int srcHeight = h;
int dstWidth = (int)(w*scal_x+0.5f);
int dstHeight = (int)(h*scal_y+0.5f);
for(int i=0; i<dstHeight;i++)
{
float y_inverse_map = (float)i/scal_y;
int y_lt = (int)y_inverse_map;
float v=y_inverse_map - y_lt;
int indexBase = i *wid;
for(int j=0;j<dstWidth;j++)
{
float x_inverse_map = (float)j/scal_x;
int x_lt = (int) x_inverse_map;
float u=x_inverse_map - x_lt;
int index = indexBase + j*3;
*(lpData+index) = Src[y_lt*((w*24+31)/32*4)+x_lt*3];
*(lpData+index+1) = Src[y_lt*((w*24+31)/32*4)+x_lt*3+1];
*(lpData+index+2) = Src[y_lt*((w*24+31)/32*4)+x_lt*3+2];
// int r,g,b;
//((interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight,&r,&g,&b))) ;
// *(lpData+temp) = b;
//*(lpData+index++) = (BYTE)((interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight)>>16)) & 0x000000ff;
// (interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight,&r,&g,&b));
// *(lpData+temp+1) = g;
// (interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight,&r,&g,&b));
// *(lpData+temp+2) =r;
}
}
GlobalUnlock(hDIB);
GlobalUnlock(hDIB2);
return hDIB2;
}
//cwh 01.6.20
/*****************************************
卷积核心算法
*****************************************/
void DIB::interPolate(LPBYTE Src,int x,int y, float u,float v, int scanw, int scanh,int *r,int *g,int *b)
{
// UINT r11,g11,b11;
//r=g=b=0;
int red1[2][2];
int green1[2][2];
int blue1[2][2];
int xx1[2];
int yy1[2];
xx1[0]=x*3;xx1[1]=x*3+3;
yy1[0]=y;yy1[1]=y+1;
if(xx1[1]>scanw-1)
xx1[1] = scanw-1;
if(yy1[1]>scanh-1)
yy1[1] = scanh-1;
for(int i=0;i<2;i++)
{
int indexBase1 = yy1[i]*((scanw*24+31)/32*4);
for(int j=0;j<2;j++)
{
int index1 = indexBase1 + xx1[j];
blue1[j][i] = (*(Src+index1));
green1[j][i] = (*(Src+index1+1));
red1[j][i] = (*(Src+index1+2));
}
}
//r11 = ((1-u)*(1-v)*red1[0][0]+(1-u)*v*red1[0][1]+u*(1-v)*red1[1][0]+u*v*red1[1][1]);
// g11 = ((1-u)*(1-v)*green1[0][0]+(1-u)*v*green1[0][1]+u*(1-v)*green1[1][0]+u*v*green1[1][1]);
//b11 = ((1-u)*(1-v)*blue1[0][0]+(1-u)*v*blue1[0][1]+u*(1-v)*blue1[1][0]+u*v*blue1[1][1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -