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

📄 imageview.cpp

📁 BCAM 1394 Driver
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//  (c) 2002 by Basler Vision Technologies
//  Section:  Vision Components
//  Project:  BCAM
//  $Header: ImageView.cpp, 10, 17.09.2003 17:15:57, Nebelung, H.$
//-----------------------------------------------------------------------------
/**
  \file     ImageView.cpp
 *
 * \brief Implementation of CImageRectTracker and CImageView
 *
  
 */
//-----------------------------------------------------------------------------
 
#include "stdafx.h"
#include "RectTracker.h"
#include "imageview.h"



/////////////////////////////////////////////////////////////////////////////
// CImageRectTracker

CImageRectTracker::CImageRectTracker(CImageView& view)
  : CRectTracker(CRect(0,0,0,0), solidLine | resizeOutside | hatchedBorder),
    m_View(view)
{
    m_nHandleSize = 8;
}

void CImageRectTracker::AdjustRect(int nHandle, LPRECT lpRect)
{

  // CRectTracker constraints on rectangle dimensions. 
  CRectTracker::AdjustRect(nHandle, lpRect); 

  // Enforce rect inside image canvas and adjusted to valid AOI positions and sizes
  m_View.AdjustRect(nHandle, lpRect);  

}

void CImageRectTracker::AdjustPoint(LPPOINT lpPoint)
{
  m_View.AdjustPoint(lpPoint);
}

void CImageRectTracker::OnChangedRect(const CRect& rcOld )
{
  m_View.MoveTrackerTo(&m_rect, &rcOld, TRUE);
  CRectTracker::OnChangedRect(rcOld);  
}

void CImageRectTracker::OnTrackingFinished(BOOL bCancelled )
{

  m_View.StopTimer();
  
  if ( ! bCancelled )
  {
    m_View.SetNewAOI( );
  }
  else
  {
    m_View.MoveTrackerTo(m_rect, m_rectSave, TRUE);
    m_View.SetNewAOI();
  }

  CRectTracker::OnTrackingFinished(bCancelled);
}


void CImageRectTracker::LPtoDP(LPPOINT lpPoints, int nCount) const 
{ 
  m_View.LPtoDP( lpPoints, nCount);
};

void CImageRectTracker::DPtoLP(LPPOINT lpPoints, int nCount) const
{ 
  m_View.DPtoLP( lpPoints, nCount);
};



/////////////////////////////////////////////////////////////////////////////
// CImageView

const CSize CImageView::s_sizBorder = CSize(10,10);
DWORD CImageView::s_dwDragTimerInterval = 100;


void CImageView::SetSensorSize(CSize SensorSize)
{
  if ( m_VideoFormat == DCS_Format7)
  {
    // we only allow AOI widths which are multiples of 4, so the sensor rect has to be adjusted
    m_pCamera->AlignAOI(SensorSize, m_VideoMode);
  }
  m_SensorSize = SensorSize;
  m_SensorRect = CRect(CPoint(0,0), SensorSize);

  double ZoomLevel = m_dZoomScale;  // SetScrollSize resets the zoom level to 1 -> save current zoom state
  SetScrollSize(SensorSize.cx + ( 2 * s_sizBorder.cx ),  SensorSize.cy + ( s_sizBorder.cy * 2 ) );
  if ( ZoomLevel != 1 )
  {  // restore zoom state
    SetZoomLevel(ZoomLevel);
    UpdateViewPort(NULL);
 }
 
}

void CImageView::ConfigurationChanged(DCSVideoFormat format, DCSVideoMode mode, CSize SensorSize, CSize ImageSize, CPoint Origin)
{
  if ( format == DCS_Format7 )
  {
    m_pCamera->AlignAOI(SensorSize, mode);
  }
  if ( m_VideoFormat != format  || m_VideoMode != mode || m_SensorSize != SensorSize  )
  {
    m_bFit = false;
    m_VideoFormat = format;
    m_VideoMode = mode;

    if ( SensorSize != m_SensorSize )
    {
      SetSensorSize(SensorSize);
    }

    m_bScalable = format == DCS_Format7;
    if ( m_bScalable )
    {
      m_SizeInc.cx = lcm(4, m_pCamera->FormatSeven[mode].Size.Inc().cx);
      m_SizeInc.cy = m_pCamera->FormatSeven[mode].Size.Inc().cy;
      m_PosInc = m_pCamera->FormatSeven[mode].Position.Inc();
      m_RectTracker.m_sizeMin = CSize(m_SizeInc.cx, m_SizeInc.cy );
    }

  }

  CRect imageRect = CRect(Origin, ImageSize);
  m_RectTracker.m_rect = imageRect;

  // if area of interest is not visible -> center viewport on AOI
  if ( m_bScalable )
  {
    CRect client;
    GetClientRect(&client);
    ClientToLogical(client);
    client.IntersectRect(imageRect, client);
    if ( client.IsRectEmpty() )
      UpdateViewPort(NULL);
  }

  Invalidate();
  UpdateWindow();
  
  ShowAOISize();
}


void CImageView::DoPaint(CDCHandle dc) 
{
  assert(m_pCamera != NULL );
  CBcamBitmap* pBitmap = m_pCamera->GetBitmap();
  if ( pBitmap != NULL )
  {

    // Bitblt bitmap
    BitBlt(dc, pBitmap);


    // if size of image is less than size of sensor fill the parts of the sensor not
    // covered by the image
    CRect ImageRect = pBitmap->GetRect();  // image dimension
    
    HBRUSH hBrush = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
    
    if ( ImageRect.left > m_SensorRect.left )
    {
      RECT rectLeft = m_SensorRect;
      rectLeft.right = ImageRect.left;
      dc.FillRect(&rectLeft, hBrush);
    }

    if ( ImageRect.top > m_SensorRect.top )
    {
      RECT rectTop = m_SensorRect;
      rectTop.bottom = ImageRect.top;
      dc.FillRect(&rectTop, hBrush);
    }

    if ( ImageRect.right < m_SensorRect.right )
    {
      RECT rectRight = m_SensorRect;
      rectRight.left = ImageRect.right;
      dc.FillRect(&rectRight, hBrush);
    }

    if ( ImageRect.bottom < m_SensorRect.bottom  )
    {
      RECT rectBottom  = m_SensorRect;
      rectBottom.top = ImageRect.bottom;
      dc.FillRect(&rectBottom, hBrush);
    }  
  }
  else
  {
    // no bitmap available -> fill the whole sensor area
    dc.FillRect(&m_SensorRect, (HBRUSH) GetStockObject(LTGRAY_BRUSH));
  } 

  // draw bounding rectangle around sensor area
  CRect BorderRect = m_SensorRect;
  BorderRect.InflateRect(1,1);
  HBRUSH oldBrush = dc.SelectStockBrush(NULL_BRUSH);
  dc.Rectangle(&BorderRect);
  dc.SelectBrush(oldBrush); 

  // draw rubber band
  if ( m_bScalable )
  {
    m_RectTracker.Draw(dc);
  }
  
}

void CImageView::ZoomToFit()
{

  if ( ! m_bFit )
  {

    // ensure that actually no scroll bars are visible
    m_sizeAll = CSize(0,0);
    RecalcBars();

    double scale;
    bool modifyWidth;
    double scaley =  (double) ( m_sizeClient.cy - 2 * s_sizBorder.cy ) / (double) m_SensorSize.cy;
    double scalex = (double) ( m_sizeClient.cx  - 2 * s_sizBorder.cx ) / (double) m_SensorSize.cx;
    if ( scalex < scaley )
    {
      scale = scalex;
      modifyWidth = false;
    }
    else
    {
      scale = scaley;
      modifyWidth = true;
    }

    SetZoomLevel(scale); 
    ZoomIn(NULL, 0);


    if ( ! ::IsZoomed(GetParent()) )
    {
      // Adjust window dimension

      CRect newRect(CPoint(0,0), m_sizeClient);
      
      // first calculate new client size 
      if ( modifyWidth )
        newRect.right = 2 * s_sizBorder.cx + m_SensorSize.cx * scale;
      else
        newRect.bottom = 2 * s_sizBorder.cy + m_SensorSize.cy * scale;
      // transform client rect to window rect of inner window
      AdjustWindowRectEx(&newRect, GetWindowLong(GWL_STYLE), FALSE,GetWindowLong(GWL_EXSTYLE));
      // The window rect of the inner window is the desired client rect of the outer window (i.e. the MDI Child window). 
      // Calculate the window rect of the MDI window from the desired client rect
      AdjustWindowRectEx(&newRect, ::GetWindowLong(GetParent(), GWL_STYLE), FALSE, ::GetWindowLong(GetParent(), GWL_EXSTYLE));
      
      // Set the new window rect of the MDI window
      CRect oldRect;
      ::GetWindowRect(GetParent(), &oldRect);
      if ( modifyWidth )
        ::SetWindowPos(GetParent(), NULL, 0, 0, newRect.Width(), oldRect.Height(), SWP_NOMOVE | SWP_NOZORDER );
      else
        ::SetWindowPos(GetParent(), NULL, 0, 0, oldRect.Width(), newRect.Height(), SWP_NOMOVE | SWP_NOZORDER );
    }
    
    m_bFit = true;
  }

}




void CImageView::BitBlt(CDCHandle dc, CBcamBitmap* pBitmap) {

  if ( pBitmap == NULL )
    return;

  m_CriticalSection.Lock();

  PrepareDC(dc);

  // determine region of bitmap which has to be blitted

  // first get client rect and transform it into the sensor coordinate system
  CRect rect;
  GetClientRect(rect);
  dc.DPtoLP(rect);
  rect.InflateRect(1,1);

  CRect ImageRect = pBitmap->GetRect();  // image dimensions
  
  rect.IntersectRect(rect, ImageRect);


  CDC dcMem;
  dcMem.CreateCompatibleDC(dc);
  HBITMAP hBmpOld = dcMem.SelectBitmap(*pBitmap);

  if ( m_dZoomScale < 1 )
  {
    dc.SetStretchBltMode(COLORONCOLOR);
  }

  if ( m_dZoomScale > 1 )
  {
    // we observed that the performance of StretchBlt may dramatically decrease if the mouse cursor 
    // is placed outside the bitmap window. To avoid this strange behaviour we do a kind of magic. Selecting a 
    // clipping region according to the bitmapsize and reducing it by one single pixel will increase the performance
    // of StretchBlt
  
    CRgn rgn;
    CRect ClipRect = rect;
    dc.LPtoDP(ClipRect);
  
    dc.SaveDC();
    rgn.CreateRectRgnIndirect(ClipRect);
    dc.SelectClipRgn(rgn);
    CRect rect2(0, 0, 1, 1);
    rect2.OffsetRect(max(ClipRect.left, 0), max(ClipRect.top,0));
    CRgn rgn2;
    rgn2.CreateRectRgnIndirect(rect2);
    dc.SelectClipRgn(rgn2, RGN_DIFF);
  }

  dc.BitBlt(
    rect.left,
    rect.top, 
    rect.Width(), 
    rect.Height(), 
    dcMem, 
    rect.left - ImageRect.left, 
    rect.top - ImageRect.top, 
    SRCCOPY
    );   

  if ( m_dZoomScale > 1 )
    dc.RestoreDC(-1);
  
  dcMem.SelectBitmap(hBmpOld);

  if ( m_bScalable && ! ImageRect.EqualRect(m_RectTracker.m_rect) )
  {
      m_RectTracker.Draw(dc);
  }

  m_CriticalSection.Unlock();

}


LRESULT CImageView::OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
  
  assert ( m_pCamera );

  CDCHandle dc = (HDC)wParam;
  CRect ClientRect;
  GetClientRect(&ClientRect);

  CPoint pt;
  pt.x = m_SensorSize.cx;
  pt.y = m_SensorSize.cy;
  
  PrepareDC(dc);  
  
  dc.DPtoLP(&ClientRect);
  ClientRect.InflateRect(1,1);
  
  if ( ClientRect.left < 0 )
  {
    RECT ClientRectLeft = ClientRect;
    ClientRectLeft.right = 0;
    ClientRectLeft.bottom = pt.y;
    dc.FillRect(&ClientRectLeft, (HBRUSH) GetStockObject(GRAY_BRUSH));
  }
  
  if ( ClientRect.top < 0 )
  {
    RECT ClientRectTop = ClientRect;
    ClientRectTop.bottom = 0;
    dc.FillRect(&ClientRectTop, (HBRUSH) GetStockObject(GRAY_BRUSH));
  }
  
  if( ClientRect.right > m_SensorSize.cx )
  {
    RECT ClientRectRight = ClientRect;
    ClientRectRight.left = pt.x;
    ClientRectRight.bottom = pt.y;
    dc.FillRect(&ClientRectRight, (HBRUSH) GetStockObject(GRAY_BRUSH));
  }
  
  if( ClientRect.bottom > m_SensorSize.cy )
  {
    RECT ClientRectBottom = ClientRect;
    ClientRectBottom.top = pt.y;
    dc.FillRect(&ClientRectBottom, (HBRUSH) GetStockObject(GRAY_BRUSH));
  } 
  
  return 0;    
}


BOOL CImageView::HitTestTrackerBorder()
{
  if ( ! m_bScalable )
    return FALSE;

  CPoint point;
  GetCursorPos(&point);
  ScreenToClient(&point);

  CRect rcTrueRect;
  m_RectTracker.GetTrueRect(rcTrueRect);

  CRect rcTracker = m_RectTracker.m_rect;
  LogicalToClient(rcTracker);
  return rcTrueRect.PtInRect(point) && !rcTracker.PtInRect(point);
}

BOOL CImageView::MoveTrackerTo(CRect rcNew, CRect rcOld, BOOL fRepaint)
{
  if ( m_bScalable )
  {
    if (fRepaint)
    {
      Invalidate();
    }  
  }

  return TRUE;
}

void CImageView::AdjustRect(int nHandle, LPRECT lpRect)
{
  CRect rc(*lpRect);

  CRect rcLimits = m_SensorRect;
  
  if ( nHandle == CRectTracker::hitLeft ||
    nHandle == CRectTracker::hitTopLeft ||
    nHandle == CRectTracker::hitBottomLeft )
  {
    int width = m_SizeInc.cx * ( rc.Width() / m_SizeInc.cx );

    rc.left = rc.right - width;
    if ( rc.left < 0 )
    {
      rc.left = 0;
      rc.right = m_SizeInc.cx * ( rc.right / m_SizeInc.cx );
    }
  }
  
  if ( nHandle == CRectTracker::hitRight ||
    nHandle == CRectTracker::hitTopRight ||
    nHandle == CRectTracker::hitBottomRight )
  {
    int width = m_SizeInc.cx * ( rc.Width() / m_SizeInc.cx );

    rc.right = rc.left + width;
    if ( rc.right > rcLimits.right )
    {
      rc.right = rcLimits.right;
      rc.left = max(0, rc.right - m_SizeInc.cx * ( rc.Width() / m_SizeInc.cx ));
    }
  }
  
  if ( nHandle == CRectTracker::hitTopLeft ||

⌨️ 快捷键说明

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