新建一个MFC工程文件,然后想显示一幅图片,统计图片的黑白像素个数,
设置在文件打开菜单中打开一幅图像,在自己建的菜单中统计个数,如下:
打开菜单对应函数
- void CTestDoc::OnFileOpen()
- {
- // TODO: Add your command handler code here
- LPCTSTR lpszFilter= "BMPFiles(*.bmp)|*.bmp|所有文件|*.*||";
- CFileDialog dlg1(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL);
- CString filename;
- CFile file;
- if(dlg1.DoModal()==IDOK)
- {
- filename=dlg1.GetPathName();
- if(file.Open(filename,CFile::modeRead|CFile::shareDenyNone,NULL)==1)
- {
- file.Read(&bf,sizeof(bf));
- }
- file.Read(&bi,sizeof(bi));
- numQuad=0;
- if(bi.biBitCount<24)
- {
- numQuad=1<<bi.biBitCount;
- }
- pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
- memcpy(pbi,&bi,sizeof(bi));
- quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER));
- file.Read(quad,sizeof(RGBQUAD)*numQuad);
- bi.biSizeImage=bf.bfSize-bf.bfOffBits;
- lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);
- lpDIBBits=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);
- lpNewDIBBits=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);
- file.Read(lpBuf,bi.biSizeImage);
- memcpy(lpDIBBits,lpBuf,bi.biSizeImage);
- file.Close();
- }
- flag=1 ;
- }
- Ondraw函数如下:
- void CTestView::OnDraw(CDC* pDC)
- {
- CTestDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // TODO: add draw code for native data here
- if(pDoc->flag==1)
- {
- SetDIBitsToDevice(pDC->m_hDC,0,0,pDoc->bi.biWidth,pDoc->bi.biHeight,0,0,0,pDoc->bi.biHeight,pDoc->lpBuf,pDoc->pbi,DIB_RGB_COLORS);
- SetDIBitsToDevice(pDC->m_hDC,pDoc->bi.biWidth,0,pDoc->bi.biWidth,pDoc->bi.biHeight,0,0,0,pDoc->bi.biHeight,pDoc->lpDIBBits,pDoc->pbi,DIB_RGB_COLORS);
- }
- Invalidate(FALSE);
- }
- //统计函数
- void CTestView::OnCount()
- {
- // TODO: Add your command handler code here
- // TODO: Add your command handler code here
- CTestDoc* pDoc=GetDocument();
- int count,count2;
- count=0;count2=0;
- for(int i=0;i<pDoc->bi.biHeight;i++)
- {
- for(int j=0;j<pDoc->bi.biWidth;j++)
- {
- if(pDoc->lpDIBBits[pDoc->bi.biWidth*3*i+3*j]==255)
- {
- count=count+1;
- }
- else
- count2=count2+1;
- }
- }
- mcount=count;
- str.Format("白色像素个数: %5d",count);
- str1.Format("黑色像素个数为: %5d",count2);
- //lpszPathName.Format("E://desktop//temp//test//SNV%d.bmp",j);
- CClientDC dc(this);
- dc.TextOut(0,490,str);
- dc.TextOut(0,510,str1);
- }
结果并没有出现我想要的TextOut的统计数字,在视图窗口上没有显示。后来发现如下面这样就可以了。
- void CTestDoc::OnFileOpen()
- {
- // TODO: Add your command handler code here
- LPCTSTR lpszFilter= "BMPFiles(*.bmp)|*.bmp|所有文件|*.*||";
- CFileDialog dlg1(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL);
- CString filename;
- CFile file;
- if(dlg1.DoModal()==IDOK)
- {
- filename=dlg1.GetPathName();
- if(file.Open(filename,CFile::modeRead|CFile::shareDenyNone,NULL)==1)
- {
- file.Read(&bf,sizeof(bf));
- }
- file.Read(&bi,sizeof(bi));
- numQuad=0;
- if(bi.biBitCount<24)
- {
- numQuad=1<<bi.biBitCount;
- }
- pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
- memcpy(pbi,&bi,sizeof(bi));
- quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER));
- file.Read(quad,sizeof(RGBQUAD)*numQuad);
- bi.biSizeImage=bf.bfSize-bf.bfOffBits;
- lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);
- lpDIBBits=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);
- lpNewDIBBits=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);
- file.Read(lpBuf,bi.biSizeImage);
- memcpy(lpDIBBits,lpBuf,bi.biSizeImage);
- file.Close();
- }
- flag=1 ;
- this->GetRoutingView()->Invalidate(FALSE);
- }
- void CTestView::OnDraw(CDC* pDC)
- {
- CTestDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // TODO: add draw code for native data here
- if(pDoc->flag==1)
- {
- SetDIBitsToDevice(pDC->m_hDC,0,0,pDoc->bi.biWidth,pDoc->bi.biHeight,0,0,0,pDoc->bi.biHeight,pDoc->lpBuf,pDoc->pbi,DIB_RGB_COLORS);
- SetDIBitsToDevice(pDC->m_hDC,pDoc->bi.biWidth,0,pDoc->bi.biWidth,pDoc->bi.biHeight,0,0,0,pDoc->bi.biHeight,pDoc->lpDIBBits,pDoc->pbi,DIB_RGB_COLORS);
- }
- }
发现又是Invalidate的问题,一般在显示一幅图片时,最好不要把Invalidate放在Ondraw里面,这样很容易重绘,却也容易出现一些不想要的图像。在这个例子中,因为在OnDraw里加入了Invalidate(),导致窗口重绘,而Ondraw函数中没有相应的TextOut代码,所以程序运行时就看不到想要显示的字符。可以如上这样修改,程序就可以出现结果了。但当窗口发生变化时,文字消失,要重点统计菜单。还有一种修改方式,就是把text Out语句放到Ondraw里面,这样,就可以一直显示了。