📄 segmentview.cpp
字号:
// SegmentView.cpp : implementation of the CSegmentView class
//
#include "stdafx.h"
#include "Segment.h"
#include "ImageDoc.h"
#include "SegmentView.h"
#include "MonochromeBitmap.h"
#include "BlobStatsDlg.h"
#include "QuadTree.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSegmentView
IMPLEMENT_DYNCREATE(CSegmentView, CScrollView)
BEGIN_MESSAGE_MAP(CSegmentView, CScrollView)
//{{AFX_MSG_MAP(CSegmentView)
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_BLOB_STATISTICS, OnBlobStatistics)
ON_UPDATE_COMMAND_UI(ID_BLOB_STATISTICS, OnUpdateBlobStatistics)
ON_COMMAND(ID_BLOB_CHOOSETEMPLATE, OnBlobChoosetemplate)
ON_UPDATE_COMMAND_UI(ID_BLOB_CHOOSETEMPLATE, OnUpdateBlobChoosetemplate)
ON_COMMAND(ID_BLOB_MATCH, OnBlobMatch)
ON_UPDATE_COMMAND_UI(ID_BLOB_MATCH, OnUpdateBlobMatch)
ON_WM_CREATE()
ON_WM_LBUTTONUP()
ON_COMMAND(ID_IMAGE_FINDBULLSEYES, OnImageFindbullseyes)
ON_UPDATE_COMMAND_UI(ID_IMAGE_FINDBULLSEYES, OnUpdateImageFindbullseyes)
ON_COMMAND(ID_VIEW_REVERSEVIDEO, OnViewReversevideo)
ON_UPDATE_COMMAND_UI(ID_VIEW_REVERSEVIDEO, OnUpdateViewReversevideo)
//}}AFX_MSG_MAP
// 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()
/////////////////////////////////////////////////////////////////////////////
// CSegmentView construction/destruction
CSegmentView::CSegmentView()
{
m_pSelectedBlob = NULL;
m_pTemplateBlob = NULL;
m_bReverseVideo = FALSE;
}
CSegmentView::~CSegmentView()
{
}
BOOL CSegmentView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CSegmentView drawing
//-----------------------------------------------------------------
//
// CSegmentView::OnDraw - Draw the bitmap and a host of blobs:
// currently selected blob
// template matching blob
// bullseye blobs
//
//-----------------------------------------------------------------
void CSegmentView::OnDraw(CDC* pDC)
{
CImageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CRect crView;
GetScrolledViewRect(crView);
DWORD dwRop = m_bReverseVideo?NOTSRCCOPY:SRCCOPY;
pDoc->StretchBlt(*pDC,crView,crView,dwRop);
if (! pDoc->IsEmpty()) {
DrawBlobs(pDC);
}
}
//-----------------------------------------------------------------
//
// CSegmentView::DrawBlobs - Oh, yeah, here's the routine in
// which we enumerate the blobs to draw
//
//-----------------------------------------------------------------
void CSegmentView::DrawBlobs(CDC *pDC)
{
CImageDoc* pDoc = GetDocument();
CMonochromeBitmap &mb = pDoc->GetMonochromeBitmap();
int nBlobs = mb.GetBlobCount();
RGBQUAD color;
CRect crView;
GetScrolledViewRect(crView);
vector<CBlob *> vBlobs;
CQuadTree<CBlob> &tree = mb.GetQuadTree();
tree.GetItems(crView,vBlobs);
for (vector<CBlob *>::iterator ppBlob = vBlobs.begin(); ppBlob != vBlobs.end(); ppBlob++) {
CBlob *pBlob = *ppBlob;
CRect crBlob;
pBlob->GetRect(crBlob);
memset(&color,0,sizeof(color));
if (pBlob == m_pSelectedBlob) {
color.rgbGreen = 255;
} else {
color.rgbRed = 255;
}
PaintBlob(pDC,*pBlob,crBlob.TopLeft(),color);
}
if (m_pTemplateBlob != NULL && m_pSelectedBlob != NULL) {
CRect crTemplate;
GetTemplateRect(crTemplate);
memset(&color,0,sizeof(color));
color.rgbBlue = 255;
PaintBlob(pDC,*m_pTemplateBlob,crTemplate.TopLeft(),color);
}
memset(&color,0,sizeof(color));
color.rgbGreen = 255;
color.rgbRed = 255;
for (vector<CBlob *>::iterator ipBlob = m_blobBullseye.begin(); ipBlob != m_blobBullseye.end(); ipBlob++) {
CRect crBlob;
(*ipBlob)->GetRect(crBlob);
PaintBlob(pDC,**ipBlob,crBlob.TopLeft(),color);
}
}
//-----------------------------------------------------------------
//
// CSegmentView::PaintBlob - This paints one blob in the dc.
//
// pDC - paint the blob outline on this DC
// blob - paint this blob's outline.
// ptOffset - offset the bitmap by this much.
// color - paint the outline using this color.
//
//-----------------------------------------------------------------
void CSegmentView::PaintBlob(CDC * pDC, CBlob & blob, CPoint ptOffset,RGBQUAD &color)
{
CRect crView;
GetScrolledViewRect(crView);
CRect crScratch;
blob.GetRect(crScratch);
CRect crBlob(ptOffset,crScratch.Size());
CRect crIntersect;
if (crIntersect.IntersectRect(crBlob,crView)) {
// The blob is at least partially within the view.
CString cszBuffer;
BITMAPINFO *pBMI = (BITMAPINFO *)(cszBuffer.GetBuffer(sizeof(BITMAPINFO) + sizeof(RGBQUAD)));
RGBQUAD *pColors = pBMI->bmiColors;
CByteArray bMemory;
bMemory.SetSize(blob.GetDIBSize());
BYTE *pMemory = bMemory.GetData();
blob.GetDIB(pBMI->bmiHeader,pMemory);
// Why does Microsoft think so little of StretchDIBits
// that it doesn't provide a wrapper for it in MFC?
// We do that color masking thing here.
// First, AND the inverse of the monochrome bitmap onto
// the DC, then OR the real thing.
memset(pColors,0,sizeof(RGBQUAD)*2);
pColors[0].rgbRed = pColors[0].rgbBlue = pColors[0].rgbGreen = 255;
StretchDIBits(pDC->m_hDC,crBlob.left,crBlob.top,
crBlob.Width(),crBlob.Height(),
0,0,
crBlob.Width(),crBlob.Height(),
pMemory,pBMI,
DIB_RGB_COLORS,SRCAND);
pColors[0].rgbRed = pColors[0].rgbBlue = pColors[0].rgbGreen = 0;
memcpy(pColors + 1,&color,sizeof(color));
StretchDIBits(pDC->m_hDC,crBlob.left,crBlob.top,
crBlob.Width(),crBlob.Height(),
0,0,
crBlob.Width(),crBlob.Height(),
pMemory,pBMI,
DIB_RGB_COLORS,SRCPAINT);
}
}
//-----------------------------------------------------------------
//
// CSegmentView::OnInitialUpdate - Figure out the image size on the
// first update. Also, build blobs for the image.
//
//-----------------------------------------------------------------
void CSegmentView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CImageDoc *pDoc = GetDocument();
CSize sizeTotal(pDoc->Width(),pDoc->Height());
// TODO: calculate the total size of this view
SetScrollSizes(MM_TEXT, sizeTotal);
if (sizeTotal.cx != 0 && sizeTotal.cy != 0) {
pDoc->GetMonochromeBitmap().BuildBlobList();
}
}
/////////////////////////////////////////////////////////////////////////////
// CSegmentView printing
//-----------------------------------------------------------------
//
// CSegmentView::OnPreparePrinting - I have no idea if printing really works...
//
//-----------------------------------------------------------------
BOOL CSegmentView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CSegmentView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CSegmentView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CSegmentView diagnostics
#ifdef _DEBUG
void CSegmentView::AssertValid() const
{
CScrollView::AssertValid();
}
void CSegmentView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CImageDoc* CSegmentView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImageDoc)));
return (CImageDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSegmentView message handlers
//-----------------------------------------------------------------
//
// CSegmentView::GetScrolledViewRect - This returns the rectangle
// being viewed by the user.
//
//-----------------------------------------------------------------
void CSegmentView::GetScrolledViewRect(CRect & cr)
{
CRect crView;
GetClientRect(&crView);
CPoint ptScroll(GetScrollPos(SB_HORZ),GetScrollPos(SB_VERT));
cr = CRect(ptScroll,crView.Size());
}
//-----------------------------------------------------------------
//
// CSegmentView::OnLButtonDown - Select a blob on left mouse button down.
// Also, match the selected blob against the template
// blob and display the result in a fake tool tip.
//
//-----------------------------------------------------------------
void CSegmentView::OnLButtonDown(UINT nFlags, CPoint point)
{
CMonochromeBitmap &mb = GetDocument()->GetMonochromeBitmap();
int nBlobs = mb.GetBlobCount();
CPoint ptClient = point;
ClientToBitmap(point);
for (int i = 0; i < nBlobs; i++) {
CBlob *pBlob = mb.GetBlob(i);
if (pBlob->PtInBlob(point)) {
// Invalidate the currently selected blob
// and the blob-to-be.
CRect cr;
if (m_pSelectedBlob != NULL) {
m_pSelectedBlob->GetRect(cr);
BitmapToClient(cr);
InvalidateRect(cr);
if (m_pTemplateBlob) {
GetTemplateRect(cr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -