📄 lapls.cpp
字号:
DstBufSize=(DWORD)(sizeof(BITMAPINFOHEADER)+NewNumColors*sizeof(RGBQUAD)+(DWORD)DstLineBytes*bi.biHeight);
//DstBf和DstBi为新的BITMAPFILEHEADER和BITMAPINFOHEADER
//拷贝原来的头信息
::memcpy((char *)&DstBf,(char*)&bf,sizeof(BITMAPFILEHEADER));
::memcpy((char *)&DstBi,(char*)&bi,sizeof(BITMAPINFOHEADER));
//做必要的改变
DstBf.bfSize=DstBufSize+sizeof(BITMAPFILEHEADER);
DstBf.bfOffBits=(DWORD)(NewNumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
DstBi.biClrUsed=0;
DstBi.biBitCount=NewBitCount;
//原图的缓冲区的大小
SrcBufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
if((hTempImgData=LocalAlloc(LHND,DstBufSize))==NULL)
{
AfxMessageBox("Error alloc memory!",MB_OK|MB_ICONEXCLAMATION);
return NULL;
}
lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);//锁住一个全局内存块句柄,并返回指向内容的第一个字节的指针
lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);//锁住一个局部内存块句柄,并返回指向内容的第一个字节的指针
//拷贝头信息和位图数据
::memcpy(lpTempImgData,lpImgData,DstBufSize);//把lpImagData的内容拷到lpTempImagData
//用新的BITMAPINFOHEADER替换原来的头信息
::memcpy(lpTempImgData,(char*)&DstBi,sizeof(BITMAPINFOHEADER));//把DstBi的内容追加到lpTempImagData
//lpPtr指向原图的数据
lpPtr=(char *)lpImgData+sizeof(BITMAPINFOHEADER);
//lpTempPtr指向新图的数据
lpTempPtr=(char*)lpTempImgData+sizeof(BITMAPINFOHEADER);
//为新的调色板分配内存
hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) +NewNumColors* sizeof(PALETTEENTRY));
pPal =(LOGPALETTE *)LocalLock(hPal);
pPal->palNumEntries =(WORD) NewNumColors;//填写逻辑调色板结构的头
pPal->palVersion = 0x300;//填写逻辑调色板结构的头
if(NumColors==0) //真彩色
for (i = 0; i < 256; i++) { //灰度从(0,0,0)到(255,255,255),填充调色板,并填写RGBQUAD结构
pPal->palPalEntry[i].peRed=(BYTE)i;
pPal->palPalEntry[i].peGreen=(BYTE)i;
pPal->palPalEntry[i].peBlue=(BYTE)i;
pPal->palPalEntry[i].peFlags=(BYTE)0;
*(lpTempPtr++)=(unsigned char)i;
*(lpTempPtr++)=(unsigned char)i;
*(lpTempPtr++)=(unsigned char)i;
*(lpTempPtr++)=0;
}
else
for (i = 0; i < NewNumColors; i++) { //带调色板的彩色图
Blue=(unsigned char )(*lpPtr++);
Green=(unsigned char )(*lpPtr++);
Red=(unsigned char )(*lpPtr++);
//Y=(float)(Red*0.299+Green*0.587+Blue*0.114);
Y=(float)(Red*0.11+Green*0.59+Blue*0.3);
Gray=(BYTE)Y;
lpPtr++;
//从原来的调色板中的颜色计算得到Y值,写入新的调色板
pPal->palPalEntry[i].peRed=Gray;
pPal->palPalEntry[i].peGreen=Gray;
pPal->palPalEntry[i].peBlue=Gray;
pPal->palPalEntry[i].peFlags=0;
*(lpTempPtr++)=(unsigned char)Gray;
*(lpTempPtr++)=(unsigned char)Gray;
*(lpTempPtr++)=(unsigned char)Gray;
*(lpTempPtr++)=0;
}
if(hPalette!=NULL)
DeleteObject(hPalette);
//生成新的逻辑调色板
hPalette=CreatePalette(pPal);
LocalUnlock(hPal);
LocalFree(hPal);
hDc=::GetDC(hpic);
if(hPalette){
hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
RealizePalette(hDc);
}
if(NumColors==0) //真彩色图才需要处理位图数据
for(y=0;y<bi.biHeight;y++){
lpPtr=(char *)lpImgData+(SrcBufSize-LineBytes-y*LineBytes);
lpTempPtr=(char *)lpTempImgData+(DstBufSize-DstLineBytes-y*DstLineBytes);
for(x=0;x<bi.biWidth;x++){
Blue=(unsigned char )(*lpPtr++);
Green=(unsigned char )(*lpPtr++);
Red=(unsigned char )(*lpPtr++);
//Y=(float)(Red*0.299+Green*0.587+Blue*0.114);
Y=(float)(Red*0.11+Green*0.59+Blue*0.3);
//从位图数据计算得到Y值,写入新图中
Gray=(BYTE)Y;
*(lpTempPtr++)=(unsigned char)Gray;
}
}
if(hBitmap!=NULL)
DeleteObject(hBitmap);
//产生新的位图
hBitmap=CreateDIBitmap(hDc,
(LPBITMAPINFOHEADER)lpTempImgData, (LONG)CBM_INIT,
(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +
NewNumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData,
DIB_RGB_COLORS);
/*CPicture pic;
pic.ShowPic(hBitmap,hWnd,IDC_PIC_LIB);*/
if(hPalette && hPrevPalette){
SelectPalette(hDc,hPrevPalette,FALSE);
RealizePalette(hDc);
}
hf=_lcreat("c:\\gray.bmp",0);
_lwrite(hf,(LPSTR)&DstBf,sizeof(BITMAPFILEHEADER));
_lwrite(hf,(LPSTR)lpTempImgData,DstBufSize);
_lclose(hf);
//释放内存和资源
::ReleaseDC(hpic,hDc);
LocalUnlock(hTempImgData);
LocalFree(hTempImgData);
GlobalUnlock(hImgData);
return hBitmap;
}
HBITMAP CLapls::MedianFilter(HWND hWnd,BOOL Hori)
{
DWORD OffBits,BufSize;
LPBITMAPINFOHEADER lpImgData;
LPSTR lpPtr;
HLOCAL hTempImgData;
LPBITMAPINFOHEADER lpTempImgData;
LPSTR lpTempPtr;
HDC hDc;
HFILE hf;
LONG x,y;
int g,g1,g2,g3;
//OffBits为BITMAPINFOHEADER结构长度加调色板的大小
OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);
BufSize=OffBits+bi.biHeight*LineBytes;//要开的缓冲区的大小
if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
{
AfxMessageBox("Error alloc memory!",MB_OK|MB_ICONEXCLAMATION);
return NULL;
}
lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
//拷贝头信息及位图数据
memcpy(lpTempImgData,lpImgData,BufSize);
//注意边界点不处理,所以y从1到高度-2,x类似
for(y=1;y<bi.biHeight-1;y++)
for(x=1;x<bi.biWidth-1;x++){
lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+x;
lpTempPtr=(char*)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+x;
g2=(unsigned char)*(lpPtr);
if(Hori==FALSE){ //水平方向
g1=(unsigned char)*(lpPtr-1); //左邻点
g3=(unsigned char)*(lpPtr+1); //右邻点
}
else{ //垂直方向
g1=(unsigned char)*(lpPtr+LineBytes); //上邻点
g3=(unsigned char)*(lpPtr-LineBytes); //下邻点
}
//三者取中
if(g1>g2){
if(g2>g3) g=g2;
else{
if(g1>g3) g=g3;
else g=g1;
}
}
else{ //g1<=g2
if(g1>g3) g=g1;
else{
if(g2>g3) g=g3;
else g=g2;
}
}
*lpTempPtr=(BYTE)g; //存入新的缓冲区内
}
HWND hpic=::GetDlgItem(hWnd,IDC_PIC_LIB);
hDc=::GetDC(hpic);
if(hBitmap!=NULL)
DeleteObject(hBitmap);
//产生新的位图
hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,(LONG)CBM_INIT,(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData,DIB_RGB_COLORS);
CPicture pic;
pic.ShowPic(hBitmap,hWnd,IDC_PIC_LIB);
//if(Hori) //取不同的结果文件名
hf=_lcreat("c:\\median.bmp",0);
/*else
hf=_lcreat("c:\\vmedian.bmp",0);*/
_lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));
_lwrite(hf,(LPSTR)lpTempImgData,BufSize);
_lclose(hf);
//释放内存及资源
::ReleaseDC(hpic,hDc);
LocalUnlock(hTempImgData);
LocalFree(hTempImgData);
GlobalUnlock(hImgData);
return hBitmap;
}
BOOL CLapls::Histogram(HWND hWnd, HINSTANCE hInstance)
{
DWORD OffBits,BufSize;
LPBITMAPINFOHEADER lpImagData;
LPSTR lpPtr;
int x,y;
int grayindex;
HWND hPopupWnd;
int temp;
for(grayindex=0;grayindex<256;grayindex++)
GrayTable[grayindex]=0;
OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);
BufSize=OffBits+bi.biHeight*LineBytes;
lpImagData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
for(y=0;y<bi.biHeight;y++)
{
lpPtr=(char*)lpImagData+(BufSize-LineBytes-y*LineBytes);
for(x=0;x<bi.biWidth;x++)
{
grayindex=(unsigned char)*(lpPtr++);//*(lpPtr)即象素对应调色板的地址,在灰度图里也是灰度值。
GrayTable[grayindex]++;//grayindex的值即0-256中灰度值
}
}
MaxGrayNum=0;
MinGrayNum=65535;
for(grayindex=0;grayindex<256;grayindex++)
{
temp=GrayTable[grayindex];
if(temp>MaxGrayNum)
MaxGrayNum=temp;
if(temp<MinGrayNum&&(temp>0))
MinGrayNum=temp;
}
GlobalUnlock(hImgData);
wnd=new CWnd;
wnd->CreateEx(0,AfxRegisterWndClass(0,::LoadCursor(NULL,IDC_ARROW),(HBRUSH)::GetStockObject(WHITE_BRUSH)
,::LoadIcon(NULL, IDI_APPLICATION)),"histogram",WS_OVERLAPPEDWINDOW,50,80,550,350,hWnd,NULL,NULL);
hPopupWnd=wnd->GetSafeHwnd();
if(hPopupWnd)
{
OldProc=(WNDPROC)::GetWindowLong(hPopupWnd,GWL_WNDPROC);
::SetWindowLong(hPopupWnd,GWL_WNDPROC,(LONG)WindowProc);
::ShowWindow(hPopupWnd,SW_SHOW);
::UpdateWindow(hPopupWnd);
}
return TRUE;
}
LRESULT CALLBACK WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
// TODO: 在此添加专用代码和/或调用基类
HDC hdc;
PAINTSTRUCT ps;
DWORD i;
int xstart;
static LOGPEN blp={PS_SOLID,1,1,RGB(0,0,255)};
HPEN bhp;
float a,b,temp;
char str[10];
a=(float)(265.0/(MaxGrayNum-MinGrayNum));//计算出两个图像比例系数a,b
b=(float)(270.0-a*MaxGrayNum);
if (message==WM_MOVE||message==WM_PAINT||message==WM_NCPAINT||message==WM_NCACTIVATE ||message == WM_NOTIFY)
{
hdc=BeginPaint(hWnd,&ps);
bhp=CreatePenIndirect(&blp);
SelectObject(hdc,bhp);
MoveToEx(hdc,2,270,NULL);
LineTo(hdc,518,270);
xstart=2;
for(i=0;i<256;i++)
{
MoveToEx(hdc,xstart,270,NULL);
if(GrayTable[i]!=0)
temp=(float)(a*(GrayTable[i])+b);
else
temp=0.0f;
LineTo(hdc,xstart,270-(int)temp);
if(i%16==0)
{
MoveToEx(hdc,xstart,270,NULL);
LineTo(hdc,xstart,280);
_itoa(i,str,10);//把整数转换成字符串,把整数i转换成10进制存放在str中
TextOut(hdc,xstart,285,str,strlen(str));
}
xstart+=2;
}
MoveToEx(hdc,xstart,270,NULL);
LineTo(hdc,xstart,280);
TextOut(hdc,xstart,285,"256",strlen("256"));
EndPaint(hWnd,&ps);
DeleteObject(bhp);
}
return CallWindowProc(OldProc,hWnd,message,wParam,lParam);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -