📄 dib.cpp
字号:
// DIB.cpp: implementation of the DIB class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DIB.h"
#include"math.h"
#include "Designer.h"
#define WIDTHBYTES(bits) ((bits+31)/32*4)
#define RECTWIDTH(x) (x->right-x->left)
#define RECTHEIGHT(x) (x->bottom-x->top)
#define THRESHOLDCONTRAST 40
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define PI 3.1415926
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
/////////////////////////////////////////////////////////////////////
HDIB DIB::ReadDIBFile(HANDLE hFile)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HANDLE hDIB;
HANDLE hDIBtmp;
LPBITMAPINFOHEADER lpbi;
DWORD dwRead;
dwBitsSize = GetFileSize(hFile,NULL);
hDIB = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)));
if(!hDIB)
return NULL;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
if(!lpbi)
{
GlobalFree(hDIB);
return NULL;
}
if(!ReadFile(hFile,(LPBYTE)&bmfHeader,sizeof(BITMAPFILEHEADER),&dwRead,NULL))
goto ErrExit;
if(sizeof(BITMAPFILEHEADER)!=dwRead)
goto ErrExit;
if(bmfHeader.bfType != 0x4d42)
goto ErrExit;
if(!ReadFile(hFile,(LPBYTE)lpbi,sizeof(BITMAPINFOHEADER),&dwRead,NULL))
goto ErrExit;
if(sizeof(BITMAPINFOHEADER)!= dwRead)
goto ErrExit;
GlobalUnlock(hDIB);
if(lpbi->biSizeImage==0)
lpbi->biSizeImage = (this->BytePerLine(hDIB))*lpbi->biHeight;
hDIBtmp = GlobalReAlloc(hDIB,lpbi->biSize+lpbi->biSizeImage,0);
if(!hDIBtmp)
goto ErrExitNoUnlock;
else
hDIB = hDIBtmp;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
if(bmfHeader.bfOffBits != 0L)
SetFilePointer(hFile,bmfHeader.bfOffBits,NULL,FILE_BEGIN);
if(ReadFile(hFile,(LPBYTE)lpbi+lpbi->biSize,lpbi->biSizeImage,&dwRead,NULL))
goto OKExit;
ErrExit:
GlobalUnlock(hDIB);
ErrExitNoUnlock:
GlobalFree(hDIB);
return NULL;
OKExit:
GlobalUnlock(hDIB);
return hDIB;
}
HDIB DIB::LoadDIB(LPCTSTR lpFileName)
{
HANDLE hDIB;
HANDLE hFile;
if((hFile = CreateFile(lpFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))!= INVALID_HANDLE_VALUE)
{
hDIB = ReadDIBFile(hFile);
CloseHandle(hFile);
return hDIB;
}
return NULL;
}
BOOL DIB::PaintDIBTrue(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,LPRECT lpDIBRect ,DWORD dwRop)
{
LPBYTE lpDIBHdr;
LPBYTE lpDIBBits;
BOOL bSuccess = FALSE;
if(!hDIB)
return FALSE;
lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER);
bSuccess = StretchDIBits(hDC,lpDCRect->left,
lpDCRect->top,
RECTWIDTH(lpDCRect),
RECTHEIGHT(lpDCRect),
lpDIBRect->left,
((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
RECTWIDTH(lpDIBRect),
RECTHEIGHT(lpDIBRect),
lpDIBBits,
(LPBITMAPINFO)lpDIBHdr,
DIB_RGB_COLORS,
SRCCOPY);
GlobalUnlock(hDIB);
return bSuccess;
}
WORD DIB::BytePerLine(HANDLE hDIB)
{
WORD i;
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
i = WIDTHBYTES((lpbi->biWidth)*24);
GlobalUnlock(hDIB);
return i;
}
HPALETTE DIB::CreateGrayPalette()
{
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal = NULL;
int i ;
hLogPal = GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256);
if(!hLogPal)
return NULL;
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
lpPal->palVersion = 0x300;
lpPal->palNumEntries = 256;
for(i = 0 ;i < 256; i ++)
{
lpPal->palPalEntry[i].peRed = lpPal->palPalEntry[i].peGreen = lpPal->palPalEntry[i].peBlue = i;
lpPal->palPalEntry[i].peFlags = 0 ;
}
hPal = CreatePalette(lpPal);
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return hPal;
}
BOOL DIB::PaintDIBGray(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,LPRECT lpDIBRect,HPALETTE hPal,DWORD dwRop)
{
LPBYTE lpDIBHdr;
LPBYTE lpDIBBits;
BOOL bSuccess = FALSE;
HPALETTE hOldPal = NULL;
if(!hDIB)
return FALSE;
lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
BITMAPINFOHEADER *a = (BITMAPINFOHEADER*)lpDIBHdr;
lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER);
hOldPal = SelectPalette(hDC,hPal,FALSE);
UINT i = RealizePalette(hDC);
SetStretchBltMode(hDC,COLORONCOLOR);
bSuccess = StretchDIBits(hDC,lpDCRect->left,
lpDCRect->top,
RECTWIDTH(lpDCRect),
RECTHEIGHT(lpDCRect),
lpDIBRect->left,
((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
RECTWIDTH(lpDIBRect),
RECTHEIGHT(lpDIBRect),
lpDIBBits,
(LPBITMAPINFO)lpDIBHdr,
DIB_RGB_COLORS,
SRCCOPY);
SelectPalette(hDC,hOldPal,FALSE);
return bSuccess;
}
int DIB::ColorNumDIB(HANDLE hDIB)
{
LPBITMAPINFOHEADER lpbi;
int NumColor;
if(!hDIB)
return -1;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
NumColor = lpbi->biClrUsed;
GlobalUnlock(hDIB);
return NumColor;
}
LPBYTE DIB::FindDIBBits(HANDLE hDIB)
{
LPBYTE lpDIB,lpDIBtmp;
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
lpDIBtmp = (LPBYTE)lpbi;
lpDIB = lpDIBtmp + sizeof(BITMAPINFOHEADER);
GlobalUnlock(hDIB);
return lpDIB;
}
long DIB::PixelOffset(int i,int j,WORD wBytePerLine)
{
long Offset;
Offset = i*wBytePerLine + j*3;
return Offset;
}
int DIB::BOUND(int a ,int b ,int rgb)
{
if(rgb<0)
return BOUND(a,b,abs(rgb));
if(rgb>b)
return b;
return rgb;
}
void DIB::WhiteBlack(HANDLE hDIB,unsigned n)
{
LPBITMAPINFOHEADER lpbi;
LPBYTE lpS;
int width,height;
long lOffset;
WORD wBytesPerLine;
if(!hDIB)
return ;
wBytesPerLine = this->BytePerLine(hDIB);
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
width = lpbi->biWidth;
height = lpbi->biHeight;
lpS = (LPBYTE)lpbi;
lpS = lpS + sizeof(BITMAPINFOHEADER);
for(int i = 0;i<height;i++)
for(int j = 0 ;j<width;j++)
{
lOffset = this->PixelOffset(i,j,wBytesPerLine);
if(*(lpS+lOffset)<n)
{
*(lpS+lOffset++) = 0;
*(lpS+lOffset++) = 0;
*(lpS+lOffset) = 0;
}
else
{
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
*(lpS+lOffset) = 255;
}
}
for(i=0;i<width;i++)
{
lOffset = this->PixelOffset(0,i,wBytesPerLine);
*(lpS+lOffset++)=255;
*(lpS+lOffset++)=255;
*(lpS+lOffset++)=255;
/* lOffset = this->PixelOffset(1,i,wBytesPerLine);
*(lpS+lOffset++)=255;
*(lpS+lOffset++)=255;
*(lpS+lOffset++)=255; */
}
for(i=0;i<height;i++)
{
lOffset = this->PixelOffset(i,0,wBytesPerLine);
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
/*lOffset = this->PixelOffset(i,1,wBytesPerLine);
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255; */
}
for( i=0;i<width;i++)
{
lOffset = this->PixelOffset(height-1,i,wBytesPerLine);
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
/*lOffset = this->PixelOffset(height-2,i,wBytesPerLine);
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255; */
}
for( i=0;i<height;i++)
{
lOffset = this->PixelOffset(i,width-1,wBytesPerLine);
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
/*lOffset = this->PixelOffset(i,width-2,wBytesPerLine);
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255;
*(lpS+lOffset++) = 255; */
}
GlobalUnlock(hDIB);
}
void DIB::IncreaseContrast(BYTE *pByte,int n)
{
int Low = n;
int High = 255-n;
float Grad = ((float)(High-Low))/255;
if(*pByte<=Low)
*pByte = 0;
else if ((Low<*pByte)&&(*pByte<High))
*pByte = (BYTE)((*pByte-Low)/Grad);
else
*pByte = 255;
}
HDIB DIB::ContrastEnhance(HANDLE hDIB,int n)
{
HDIB hNewDIB;
LPBITMAPINFOHEADER lpbi;
LPBYTE lpSDIBBits,lpDDIBBits;
int width,height,wBytesPerLine;
if(!hDIB)
return NULL;
wBytesPerLine = this->BytePerLine(hDIB);
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
width = lpbi->biWidth;
height = lpbi->biHeight;
lpSDIBBits = (LPBYTE)lpbi;
hNewDIB = GlobalAlloc(GHND,lpbi->biSize+lpbi->biSizeImage);
if(!hNewDIB)
return NULL;
lpDDIBBits = (LPBYTE)GlobalLock(hNewDIB);
memcpy(lpDDIBBits,lpSDIBBits,lpbi->biSize);
lpSDIBBits = lpSDIBBits + lpbi->biSize;
lpDDIBBits = lpDDIBBits + lpbi->biSize;
BYTE rgb;
long lOffset;
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
{
lOffset = this->PixelOffset(i,j,wBytesPerLine);
rgb = *(lpSDIBBits+lOffset);
this->IncreaseContrast(&rgb,n);
*(lpDDIBBits+lOffset++) = rgb;
*(lpDDIBBits+lOffset++) = rgb;
*(lpDDIBBits+lOffset ) = rgb;
}
GlobalUnlock(hDIB);
GlobalUnlock(hNewDIB);
return hNewDIB;
}
DIB::DIB()
{
}
DIB::~DIB()
{
}
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -