⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imageprocview.cpp

📁 用内存设备上下文实现图像选中区域 的判断
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ImageProcView.cpp : implementation of the CImageProcView class
//

#include "stdafx.h"
#include "ImageProc.h"

#include "ThreshDlg.h"

#ifndef IMAGEPROCVIEW_H
#define IMAGEPROCVIEW_H
#include "ImageProcView.h"
#endif

#ifndef IMAGEPROCDOC_H
#define IMAGEPROCDOC_H
#include "ImageProcDoc.h"
#endif
#include <stdlib.h>
#include <math.h>
#include <string.h>


#define PIXEL_OFFSET(i,j,nWidthBytes) (LONG)((LONG)(i)*(LONG)(nWidthBytes)+(LONG)(j)*3)

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CImageProcView

IMPLEMENT_DYNCREATE(CImageProcView, CScrollView)

BEGIN_MESSAGE_MAP(CImageProcView, CScrollView)
	//{{AFX_MSG_MAP(CImageProcView)
	ON_COMMAND(ID_FILE_OPEN_COLOR, OnFileOpenColor)
	ON_WM_PAINT()
	ON_COMMAND(ID_PROC_BINA, OnProcBina)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_UPDATE_COMMAND_UI(ID_PROC_BINA, OnUpdateProcBina)
	ON_COMMAND(ID_SELECT_POLY, OnSelectPoly)
	ON_WM_RBUTTONDOWN()
	ON_UPDATE_COMMAND_UI(ID_SELECT_POLY, OnUpdateSelectPoly)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_THRESHCHANGED,OnThreshChanged)
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CImageProcView construction/destruction

CImageProcView::CImageProcView()
{

	m_rcDIB=CRect(0,0,0,0);
	
	hdib=NULL;
	m_hdibPrebina=NULL;
//	m_pThDlg=new CThreshDlg();
	pPalette=new CPalette;

	bSelectPoly=FALSE;

	m_pinPoint.x=m_pinPoint.y=0;
	m_oldPoint.x=m_oldPoint.y=0;
	m_oldDibPoint.x=m_oldDibPoint.y=0;


	m_iRub=0;

	hdibS=NULL;
	m_nPoints=0;
}

CImageProcView::~CImageProcView()
{
	if(!hdib==NULL)
	{
		GlobalFree(hdib);
		hdib=NULL;
	}
	if(hdibS!=NULL)
	{
		GlobalFree(hdibS);
		hdibS=NULL;
	}

}

BOOL CImageProcView::PreCreateWindow(CREATESTRUCT& cs)
{
    
	//  the CREATESTRUCT cs
    //cs.style |= WS_MAXIMIZE|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX;

	return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CImageProcView drawing

void CImageProcView::OnDraw(CDC* pDC)
{
	CPalette* pPalout;
	pPalout=pDC->SelectPalette(pPalette,TRUE);
	pDC->RealizePalette();
	::PaintDIB(pDC->GetSafeHdc(),&m_rcDIB,hdib,&m_rcDIB,*pPalette);
}

void CImageProcView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();
    //	
}

/////////////////////////////////////////////////////////////////////////////
// CImageProcView printing

BOOL CImageProcView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CImageProcView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}


/////////////////////////////////////////////////////////////////////////////
// CImageProcView diagnostics

#ifdef _DEBUG
void CImageProcView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CImageProcView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CImageProcDoc* CImageProcView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImageProcDoc)));
	return (CImageProcDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CImageProcView message handlers

void CImageProcView::OnFileOpenColor() 
{
	//if(pPalette!=NULL)
	//	delete pPalette;
	HPALETTE hPal=NULL;
	//pPalette=new CPalette;	
	
	CString str;
	CString sFilter="BMP Files(*.bmp)|*.bmp||";
	CFileDialog Dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
		(LPCTSTR)sFilter,NULL);
	if(!(Dlg.DoModal()==IDOK))
	{
		this->Invalidate();
		return;
	}
	if(hdib!=NULL)
		GlobalFree(hdib);
	if(hdibS!=NULL)
	{
		GlobalFree(hdibS);
		hdibS=NULL;
	}
	str=Dlg.GetPathName();
	
	CFileException fe;	
	CFile file;
	file.Open((LPCTSTR)str,CFile::modeRead|CFile::shareDenyWrite,&fe);
	

	hdib=::ReadDIBFile(str);
	file.Close();
		
	if(!hdib)
	{
		MessageBox("Can not read file",NULL,MB_OK);
		return;
	}
	//::SaveDIBToFile(hdib,"backup.bmp");
	CImageProcDoc* pDoc=GetDocument();
	ASSERT_VALID(pDoc);		
	pDoc->m_hdib=hdib;

	LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)hdib);
	if(lpDIB==NULL)
		return;
	int cxDIB=(int)::DIBWidth(lpDIB);
	int cyDIB=(int)::DIBHeight(lpDIB);
	::GlobalUnlock((HGLOBAL)hdib);
	
	m_rcDIB.top=m_rcDIB.left=0;
	m_rcDIB.right=cxDIB;
	m_rcDIB.bottom=cyDIB;

	if(::CreateDIBPalette(hdib,&hPal)==NULL)
	{
		MessageBox("Can not Create palette",NULL,MB_OK);
	}
	else
	{
		pPalette=CPalette::FromHandle(hPal);
		this->Invalidate(TRUE);
	}	
	EndWaitCursor();
}

void CImageProcView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	CSize sizeTotal;
	
	sizeTotal.cx=m_rcDIB.right;
	sizeTotal.cy=m_rcDIB.bottom;

	SetScrollSizes(MM_TEXT,sizeTotal);
	
	OnPrepareDC(&dc);

	OnDraw(&dc);    
	// Do not call CScrollView::OnPaint() for painting messages
}





void CImageProcView::OnProcBina() 
{
	HPALETTE hPal;
	BeginWaitCursor();
	//HDIB hNewDib;
	DWORD dwDIBSize,dwImageSize;
	//BYTE iArray[256],oArray[256];
	if(!hdib)
	{
		EndWaitCursor();
		return;
	}
	LPBITMAPINFOHEADER lpBI=(LPBITMAPINFOHEADER)GlobalLock(hdib);
	if(!lpBI)
	{
		EndWaitCursor();
		return;
	}
	WORD wDIBWidth=(WORD)::DIBWidth((LPSTR)lpBI)+1;
	WORD wDIBHeight=(WORD)::DIBHeight((LPSTR)lpBI);
	if(wDIBWidth-1>1024||wDIBHeight>768)
	{
		MessageBox("图像象素点过多,无法处理!","Warning",MB_OK|MB_ICONSTOP);
		GlobalUnlock(hdib);
		lpBI=NULL;
		return;
	}
	
	dwDIBSize=*(LPDWORD)lpBI +DIBNumColors((LPSTR)lpBI) *sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER);
	WORD wBytesPerLine =(WORD)BytesPerLine(lpBI);
	dwImageSize=wBytesPerLine*wDIBHeight;
	dwDIBSize+=dwImageSize;

	m_hdibPrebina=(HDIB)GlobalAlloc(GHND,dwDIBSize);
	if(!m_hdibPrebina)
	{
		EndWaitCursor();
		return;
	}

	LPBYTE lpPrebinaImage=(LPBYTE)GlobalLock(m_hdibPrebina);
	memcpy(lpPrebinaImage,lpBI,dwDIBSize);
	
	LPBYTE lpDIBBits=(LPBYTE)FindDIBBits((LPSTR)lpBI);	
//	LPBYTE lpDestDIBBits=FindDIBBits(lpDestImage);

	for(int i=0;i<wDIBHeight-1;i++)
	{
		for(int j=0;j<wDIBWidth-1;j++)
		{
			BYTE blue,green,red,newvalue;			
			LONG lOffset=PIXEL_OFFSET(i,j,wBytesPerLine);
			LONG lDestOffset=lOffset;// lpDestOffset for color fading
			blue=*(lpDIBBits+lOffset++);
			green=*(lpDIBBits+lOffset++);
			red=*(lpDIBBits+lOffset);

			newvalue=(BYTE)(0.30*red+0.59*green+0.11*blue);
			iArray[i][j]=newvalue;	
			
        
		}
	}

	m_thresh=128;
	
	for(i=0;i<wDIBHeight-1;i++)
	{
		for(int j=0;j<wDIBWidth-1;j++)
		{
			if(bSelectPoly)
			{
				LPBITMAPINFOHEADER lpBIS=(LPBITMAPINFOHEADER)GlobalLock(hdibS);
				if(!lpBIS)
				{
					return;
				}
				LPBYTE lpDIBBitsS=(LPBYTE)FindDIBBits((LPSTR)lpBIS);
				BYTE value;			
				LONG lOffsetS=PIXEL_OFFSET(i,j,wBytesPerLine);
				value=*(lpDIBBitsS+lOffsetS);
				if(value!=0)
					continue;
			}
			BYTE blue,green,red,newvalue;			
			LONG lOffset=PIXEL_OFFSET(i,j,wBytesPerLine);
			LONG lDestOffset=lOffset;// lpDestOffset for color fading
			blue=*(lpDIBBits+lOffset++);
			green=*(lpDIBBits+lOffset++);
			red=*(lpDIBBits+lOffset);				

			newvalue=(BYTE)(0.30*red+0.59*green+0.11*blue);

			//threshUsed=min(255,m_thresh+(int)(1.1*fac*m_thresh));
			BYTE destvalue=(newvalue>m_thresh)?255:0;
		//	BYTE destvalue=(newvalue>thresh)?255:0;
			iArray[i][j]=destvalue;
			(BYTE)(*(lpDIBBits+lDestOffset++))=destvalue;			
			(BYTE)(*(lpDIBBits+lDestOffset++))=destvalue;
			(BYTE)(*(lpDIBBits+lDestOffset))=destvalue;			
		}
	}
	GlobalUnlock(hdib);
	CImageProcDoc* pDoc=GetDocument();
	ASSERT_VALID(pDoc);

	pDoc->m_hdib=hdib;
	if(::CreateDIBPalette(hdib,&hPal)==NULL)
	{
		MessageBox("Can not Create palette",NULL,MB_OK);
	}
	else
	{
		pPalette=CPalette::FromHandle(hPal);
		Invalidate();
	}
	CThreshDlg m_pThDlg;
	m_pThDlg.m_threshold=m_thresh;
	m_pThDlg.m_pView=this;
	if(m_pThDlg.DoModal()==IDOK)
	{
		if(m_hdibPrebina!=NULL)
			GlobalFree(m_hdibPrebina);
		m_hdibPrebina=NULL;
	}
	else
	{
		if(hdib!=NULL)
			GlobalFree(hdib);
		hdib=m_hdibPrebina;
		CImageProcDoc* pDoc=GetDocument();
		ASSERT_VALID(pDoc);

		pDoc->m_hdib=hdib;
		if(::CreateDIBPalette(hdib,&hPal)==NULL)
		{
			MessageBox("Can not Create palette",NULL,MB_OK);
			Invalidate();
		}
		else
		{
			pPalette=CPalette::FromHandle(hPal);
			Invalidate();
		}
	}
}







void CImageProcView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CPoint refPoint=CImageProcView::GetScrollPosition();
	
	if(bSelectPoly)
	{
		if(m_nPoints!=0)
		{
			this->Invalidate();

			m_nPoints=0;
			LPBITMAPINFOHEADER lpBI=(LPBITMAPINFOHEADER)GlobalLock(hdibS);
			if(!lpBI)
			{
				return;
			}	
			WORD wDIBWidth=(WORD)::DIBWidth((LPSTR)lpBI);
			WORD wDIBHeight=(WORD)::DIBHeight((LPSTR)lpBI);
				
			//dwDIBSize=*(LPDWORD)lpBI +DIBNumColors((LPSTR)lpBI) *sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER);
			WORD wBytesPerLine =(WORD)BytesPerLine(lpBI);
			//dwImageSize=wBytesPerLine*wDIBHeight;
			//dwDIBSize+=dwImageSize;
			
	
			LPBYTE lpDIBBits=(LPBYTE)FindDIBBits((LPSTR)lpBI);	
		//	LPBYTE lpDestDIBBits=FindDIBBits(lpDestImage);

			for(int i=0;i<wDIBHeight-1;i++)
			{
				for(int j=0;j<wDIBWidth-1;j++)
				{			
					LONG lOffset=PIXEL_OFFSET(i,j,wBytesPerLine);					
					(BYTE)(*(lpDIBBits+lOffset++))=255;
					(BYTE)(*(lpDIBBits+lOffset++))=255;
					(BYTE)(*(lpDIBBits+lOffset))=255;		
				}
			}
		}

		SetCapture();
		m_pointS[m_nPoints].x=point.x+refPoint.x;
		m_pointS[m_nPoints].y=point.y+refPoint.y;
		m_pointSL[m_nPoints].x=point.x;
		m_pointSL[m_nPoints].y=point.y;
		m_oldPointS=point;
		m_nPoints++;
	}
}

void CImageProcView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CPoint refPoint=CImageProcView::GetScrollPosition();
	
	if(bSelectPoly)
	{
		if(GetCapture()!=this)
			return;
		CClientDC dc(this);

		CDC *pDCS=PaintBeginS(&dc);	
		CPen penS(PS_SOLID,0,RGB(255,255,255));
		CBrush brushS(RGB(0,0,0));
		CBrush *pOldbrushS=pDCS->SelectObject(&brushS);
		CPen *pOldPenS=pDCS->SelectObject(&penS);

		CPen pen(PS_DOT,1,RGB(0,0,0));
		CPen *pOldPen=dc.SelectObject(&pen);

		if((point.x+refPoint.x==m_pointS[0].x)&&
			(point.y+refPoint.y==m_pointS[0].y))
		{
			dc.Polyline(m_pointS, m_nPoints);

			dc.SelectObject(pOldPen);
			pDCS->Polygon(m_pointS, m_nPoints);
			pDCS->SelectObject(pOldPenS);
			pDCS->SelectObject(pOldbrushS);	
			
			CScrollView::OnLButtonUp(nFlags, point);
			PaintEndS();
			ReleaseCapture();
			return;
		}	
		
		
		dc.MoveTo(point);
		dc.LineTo(m_pointSL[0].x,m_pointSL[0].y);
		m_pointSL[m_nPoints].x=m_pointSL[0].x;
		m_pointSL[m_nPoints].y=m_pointSL[0].y;
		dc.Polyline(m_pointSL, m_nPoints+1);
		dc.SelectObject(pOldPen);
		
		pDCS->Polygon(m_pointS, m_nPoints);
		pDCS->SelectObject(pOldPenS);
		pDCS->SelectObject(pOldbrushS);

		CScrollView::OnLButtonUp(nFlags, point);
		PaintEndS();
		ReleaseCapture();		
	}
}









int CImageProcView::GetThresh(const BYTE inArray[1024][768],const WORD wDIBWidth,const WORD wDIBHeight,
							  int *minLum,int *maxLum)
{
	int x,y;
	double bmax,bunsan[256],mean1,mean2,lum[256];
	long int noudo1=0,noudo2=0;
	long int gasosu1=0,gasosu2=0;
	int thresh,th,level=0;
	*minLum=0;
	*maxLum=255;

	for(y=0;y<wDIBHeight;y++)
	{
		for(x=0;x<wDIBWidth;x++)
		{
			if(level<inArray[y][x])
				level=inArray[y][x];
		}
	}
	for(y=0;y<wDIBHeight;y++)
	{
		for(x=0;x<wDIBWidth;x++)
		{
			int lm=inArray[y][x];
			lum[lm]++;			
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -