从上到下在内存中寻找黑白交接点,很简单的,只要查找每条线上各个像素的值,发现结果突然接近0的时候就是你要找的Y坐标.
另外:BMP的原点(0, 0)是在图片的左下方。
另外:BMP的原点(0, 0)是在图片的左下方。
解决方案 »
- 标题栏自绘//WM_ACTIVE消息要如何处理????
- VC插件编程
- =============[Windows核心编程] 进程间传递数据指针?===========
- 程序发布后出现错误。
- 关于HINSTANCE 和HANDLE 的问题
- 如何实现对编辑框输入数值进行校验?(只允许输入数值,其它的字符不行)
- 怎样在这个函数体中开**Data的内存?CreateData(BYTE **Data, int nWidth, int nHeight),谢谢!
- 关于浮动菜单的问题,着急`
- QueryInterface 中的使用的类型转换,我试了一下怎么跟书上说的不一样?
- 是高手的请进,关于截图的问题。
- 在vc中有没有关于类似vb或者delphi的属性窗体(object inspector)那样的表格控件?
- 配X-windows
#include "dibapi.h"
#include <io.h>
#include <errno.h>#include <math.h>
#include <direct.h>#define PI 3.1415926535
//*Dib文件头标志(写字符"BM",写DIB时用到该常数)
#define DIB_HEADER_MARKER ((WORD)('M'<<8)|'B')BOOL WINAPI PaintDIB(HDC hDC,LPRECT lpDCRect,HDIB hDIB,LPRECT lpDIBRect,CPalette *pPal)
{
LPSTR lpDIBHdr;
LPSTR lpDIBBits;
BOOL bSuccess=FALSE;
HPALETTE hPal=NULL;
HPALETTE hOldPal;
if(hDIB==NULL)
return FALSE;
lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
lpDIBBits=::FindDIBBits(lpDIBHdr);
if(pPal!=NULL)
{
hPal=(HPALETTE)pPal->m_hObject;
hOldPal=::SelectPalette(hDC,hPal,TRUE);
}
::SetStretchBltMode(hDC,COLORONCOLOR);
if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect))&&(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDIBRect)))
{
bSuccess=::SetDIBitsToDevice(hDC,lpDCRect->left,lpDCRect->top,
RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),
lpDIBRect->left,(int)DIBHeight(lpDIBHdr)-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
0,(WORD)DIBHeight(lpDIBHdr),lpDIBBits,
(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
}
else
{
bSuccess=::StretchDIBits(hDC,lpDCRect->left,lpDCRect->top,
RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),
lpDIBRect->left,lpDIBRect->top,
RECTWIDTH(lpDIBRect),RECTHEIGHT(lpDIBRect),
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
}
::GlobalUnlock((HGLOBAL)hDIB);
if(hOldPal!=NULL)
{
::SelectPalette(hDC,hOldPal,TRUE);
}
return bSuccess;
}
BOOL WINAPI CreateDIBPalette(HDIB hDIB,CPalette *cPal)
{
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal=NULL;
int i;
WORD wNumColors;
LPSTR lpbi;
LPBITMAPINFO lpbmi;
LPBITMAPCOREINFO lpbmc;
BOOL bWinStyleDIB;
BOOL bResult=FALSE;
if(hDIB==NULL)
return FALSE;
lpbi=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
lpbmi=(LPBITMAPINFO)lpbi;
lpbmc=(LPBITMAPCOREINFO)lpbi;
wNumColors=::DIBNumColors(lpbi);
if(wNumColors!=0)
{
hLogPal=::GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
if(hLogPal==0)
{
::GlobalUnlock((HGLOBAL)hDIB);
return FALSE;
}
lpPal=(LPLOGPALETTE)::GlobalLock((HGLOBAL)hLogPal);
lpPal->palVersion=PALVERSION;
lpPal->palNumEntries=(WORD)wNumColors;
bWinStyleDIB=IS_WIN30_DIB(lpbi);
for(i=0;i<(int)wNumColors;i++)
{
if(bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed=lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue=lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags=0;
}
else
{
lpPal->palPalEntry[i].peRed=lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen=lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue=lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags=0;
} }
bResult=cPal->CreatePalette(lpPal);
::GlobalUnlock((HGLOBAL)hLogPal);
::GlobalFree((HGLOBAL)hLogPal); }
::GlobalUnlock((HGLOBAL)hDIB);
return bResult;
}
LPSTR WINAPI FindDIBBits(LPSTR lpbi)
{
return (lpbi+*(LPDWORD)lpbi+::PaletteSize(lpbi));
}
DWORD WINAPI DIBWidth(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc; lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
return lpbmi->biWidth;
else
return (DWORD)lpbmc->bcWidth;
}
DWORD WINAPI DIBHeight(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc; lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
return lpbmi->biHeight;
else
return (DWORD)lpbmc->bcHeight;}
WORD WINAPI PaletteSize(LPSTR lpbi)
{
if(IS_WIN30_DIB(lpbi))
{
return (WORD)(::DIBNumColors(lpbi)*sizeof(RGBQUAD));
}
else
return (WORD)(::DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
}
WORD WINAPI DIBNumColors(LPSTR lpbi)
{
WORD wBitCount;
if(IS_WIN30_DIB(lpbi))
{
DWORD dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
if(dwClrUsed!=0)
return (WORD)dwClrUsed;
}
if(IS_WIN30_DIB(lpbi))
{
wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;
}
else
{
wBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
}
switch(wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0; }
}
HGLOBAL WINAPI CopyHandle(HGLOBAL h)
{
if(h==NULL)
return NULL;
DWORD dwLen=::GlobalSize((HGLOBAL)h);
HGLOBAL hCopy=::GlobalAlloc(GHND,dwLen);
if(hCopy!=NULL)
{
void *lpCopy=::GlobalLock((HGLOBAL)hCopy);
void *lp=::GlobalLock((HGLOBAL)h);
memcpy(lpCopy,lp,dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
BOOL WINAPI SaveDIB(HDIB hDib,CFile &file)
{
BITMAPFILEHEADER bmfHdr;
LPBITMAPINFOHEADER lpBI;
DWORD dwDIBSize;
if(hDib==NULL)
{
return FALSE;
}
lpBI=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
if(lpBI==NULL)
return FALSE;
if(!IS_WIN30_DIB(lpBI))
{
::GlobalUnlock((HGLOBAL)hDib);
return FALSE;
}
bmfHdr.bfType=DIB_HEADER_MARKER;
dwDIBSize=*(LPDWORD)lpBI+::PaletteSize((LPSTR)lpBI);
if((lpBI->biCompression==BI_RLE8)||(lpBI->biCompression==BI_RLE4))
dwDIBSize+=lpBI->biSizeImage;
else
{
DWORD dwBmBitsSize;
dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))*lpBI->biHeight;
dwDIBSize+=dwBmBitsSize;
lpBI->biSizeImage=dwBmBitsSize;
}
bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1=0;
bmfHdr.bfReserved2=0;
bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize+PaletteSize((LPSTR)lpBI);
TRY
{
file.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));
file.WriteHuge(lpBI,dwDIBSize);
}
CATCH(CFileException,e)
{
::GlobalUnlock((HGLOBAL)hDib);
THROW_LAST();
}
END_CATCH
::GlobalUnlock((HGLOBAL)hDib);
return TRUE;
}
HDIB WINAPI ReadDIBFile(CFile &file)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HDIB hDIB;
LPSTR pDIB;
dwBitsSize=file.GetLength();
if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))
return NULL;
if(bmfHeader.bfType!=DIB_HEADER_MARKER)
{
return NULL;
}
hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize);
if(hDIB==0)
return NULL;
pDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BITMAPFILEHEADER))!=dwBitsSize-sizeof(BITMAPFILEHEADER))
{
::GlobalUnlock((HGLOBAL)hDIB);
::GlobalFree((HGLOBAL)hDIB);
return NULL;
}
::GlobalUnlock((HGLOBAL)hDIB);
return hDIB;
}
VOID WINAPI DCT(double *f,double *F,int r)
{
long count=1<<r;
int i;
double dTemp;
complex<double>*X;
X=new complex<double>[count*2];
memset(X,0,sizeof(complex<double>)*count*2);
for(i=0;i<count;i++)
X[i]=complex<double>(f[i],0);
FFT(X,X,r+1);
dTemp=1/sqrt(count);
F[0]=X[0].real()*dTemp;
dTemp*=sqrt(2);
for(i=1;i<count;i++)
{
F[i]=(X[i].real()*cos(i*PI/(count*2))+X[i].imag()*sin(i*PI/(count*2)))*dTemp;
}
delete X;
}
VOID WINAPI IDCT(double *F,double *f,int r)
{
long count=1<<r;
int i;
double dTemp,d0;
complex<double>*X;
X=new complex<double>[count*2];
memset(X,0,sizeof(complex<double>)*count*2);
for(i=0;i<count;i++)
X[i]=complex<double>(F[i]*cos(i*PI/(count*2)),F[i]*sin(i*PI/(count*2))); IFFT(X,X,r+1);
dTemp=sqrt(2.0/count);
d0=(sqrt(1.0/count)-dTemp)*F[0];
for(i=0;i<count;i++)
f[i]=d0+X[i].real()*dTemp*2*count; delete X;
}
BOOL WINAPI DIBDct(LPSTR lpDIBBits,LONG lWidth,LONG lHeight)
{ unsigned char *lpSrc; long i,j;
long h=1,w=1;
int hp=0,wp=0;
double dTemp;
long lLineBytes=WIDTHBYTES(lWidth*8);
while(w*2<=lWidth)
{
w*=2;wp++;
}
while(h*2<=lHeight)
{
h*=2;hp++;
}
double *f=new double[w*h];
double *F=new double[w*h];
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
lpSrc=(unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-i)+j;
f[j+i*w]=*(lpSrc);
}
}
for(i=0;i<h;i++)
DCT(&f[w*i],&F[w*i],wp);
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
f[i+j*h]=F[j+i*w];
}
for(j=0;j<w;j++)
DCT(&f[j*h],&F[j*h],hp);
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
dTemp=fabs(F[j*h+i]);
if(dTemp>255)
dTemp=255;
lpSrc=(unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-i)+j;
*(lpSrc)=(BYTE)(dTemp);
}
}
delete f;
delete F;
return TRUE;
}
//===============细化========================================
BOOL WINAPI ThiningDIB(LPSTR lpDIBBits,LONG lWidth,LONG lHeight)
{ LPSTR lpSrc;
LPSTR lpDest;
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits; bool bModified=true;
long i,j;
int m,n;
bool bCondition1,bCondition2,bCondition3,bCondition4;
unsigned char nCount;
unsigned char pixel;
unsigned char neighbour[5][5];
hNewDIBBits=LocalAlloc(LHND,lWidth*lHeight);
if(hNewDIBBits==NULL)
{
return FALSE;
}
lpNewDIBBits=(char*)LocalLock(hNewDIBBits);
lpDest=(char*)lpNewDIBBits;
memset(lpDest,(BYTE)255,lWidth*lHeight); while(bModified)
{
bModified=false;
lpDest=(char*)lpNewDIBBits;
memset(lpDest,(BYTE)255,lWidth*lHeight);
for(j=2;j<lHeight-2;j++)
{
for(i=2;i<lWidth-2;i++)
{
bCondition1=false;
bCondition2=false;
bCondition3=false;
bCondition4=false;
lpSrc=(char*)lpDIBBits+lWidth*j+i;
lpDest=(char*)lpNewDIBBits+lWidth*j+i; pixel=(unsigned char)*lpSrc;
if(pixel!=255&&*lpSrc!=0)
{
return FALSE;
}
else if(pixel==255)
continue;
for(m=0;m<5;m++)
{
for(n=0;n<5;n++)
{ neighbour[m][n]=(255-(unsigned char)*(lpSrc+((4-m)-2)*lWidth+n-2))/255;
}
}
nCount=neighbour[1][1]+neighbour[1][2]+neighbour[1][3]+neighbour[2][1]+
neighbour[2][3]+neighbour[3][1]+neighbour[3][2]+neighbour[3][3];
if(nCount>=2&&nCount<=6)
bCondition1=true;
nCount=0;
if(neighbour[1][2]==0&&neighbour[1][1]==1)
nCount++;
if(neighbour[1][1]==0&&neighbour[2][1]==1)
nCount++;
if(neighbour[2][1]==0&&neighbour[3][1]==1)
nCount++;
if(neighbour[3][1]==0&&neighbour[3][2]==1)
nCount++;
if(neighbour[3][2]==0&&neighbour[3][3]==1)
nCount++;
if(neighbour[3][3]==0&&neighbour[2][3]==1)
nCount++;
if(neighbour[2][3]==0&&neighbour[1][3]==1)
nCount++;
if(neighbour[1][3]==0&&neighbour[1][2]==1)
nCount++;
if(nCount==1)
bCondition2=true; if(neighbour[1][2]*neighbour[2][1]*neighbour[2][3]==0)
bCondition3=true;
else
{
nCount=0;
if(neighbour[0][2]==0&&neighbour[0][1]==1)
nCount++;
if(neighbour[0][1]==0&&neighbour[1][1]==1)
nCount++;
if(neighbour[1][1]==0&&neighbour[2][1]==1)
nCount++;
if(neighbour[2][1]==0&&neighbour[2][2]==1)
nCount++;
if(neighbour[2][2]==0&&neighbour[2][3]==1)
nCount++;
if(neighbour[2][3]==0&&neighbour[1][3]==1)
nCount++;
if(neighbour[1][3]==0&&neighbour[0][3]==1)
nCount++;
if(neighbour[0][3]==0&&neighbour[0][2]==1)
nCount++;
if(nCount!=1)
bCondition3=true; }
if(neighbour[1][2]*neighbour[2][1]*neighbour[3][2]==0)
bCondition4=true;
else
{
nCount=0;
if(neighbour[1][1]==0&&neighbour[1][0]==1)
nCount++;
if(neighbour[1][0]==0&&neighbour[2][0]==1)
nCount++;
if(neighbour[2][0]==0&&neighbour[3][0]==1)
nCount++;
if(neighbour[3][0]==0&&neighbour[3][1]==1)
nCount++;
if(neighbour[3][1]==0&&neighbour[3][2]==1)
nCount++;
if(neighbour[3][2]==0&&neighbour[2][2]==1)
nCount++;
if(neighbour[2][2]==0&&neighbour[1][2]==1)
nCount++;
if(neighbour[1][2]==0&&neighbour[1][1]==1)
nCount++;
if(nCount!=1)
bCondition4=true;
}
if(bCondition1&&bCondition2&&bCondition3&&bCondition4)
{
*lpDest=(unsigned char)255;
bModified=true;
}
else *lpDest=(unsigned char)0;
}
}
memcpy(lpDIBBits,lpNewDIBBits,lWidth*lHeight);
}
memcpy(lpDIBBits,lpNewDIBBits,lWidth*lHeight);
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
return TRUE;
}这是我学图象处理时的代码!
如果中间一个点都没有就这样
pData 指向数据段
unsigned char *pSor;
for(i=0;i<lHeight)
{
pSor=pData+lWidht*i+91;
if(i!=lHeight-1)
{
if((*(pData+lWidht*(i+1))+91-*pSor)==255))||(*(pData+lWidht*(i+1))+91-*pSor)==-255)));//连着的两行比较一下
return i;
}
}
to: akiy(宏) 交接处就是灰的那一片,具体多灰色区域有多宽是不确定的。