Red de conocimiento informático - Material del sitio web - Cómo dibujar datos de usuario en DuiLib

Cómo dibujar datos de usuario en DuiLib

En DuiLib, a veces es necesario dibujar gráficos o imágenes en la ventana, como dibujar curvas relacionadas o procesar OpenCV los datos Mat de la imagen. En este momento, DuiLib no tiene una función directa para operar la interfaz. Este artículo describe un método de compromiso basado en Windows Win.

1. Defina la clase CWndUI para que pueda agregarse a DuiLib

clase CWndUI: public CControlUI

{

public:

CWndUI(): m_hWnd(NULL){}

virtual void SetVisible(bool bVisible = true)

{

__super: : SetVisible(bVisible);

::ShowWindow(m_hWnd, bVisible);

}

virtual void SetInternVisible(bool bVisible = true)

{

__super::SetInternVisible(bVisible);

::ShowWindow(m_hWnd, bVisible);

}

virtual void SetPos(RECT rc)

{

__super::SetPos(rc);

::SetWindowPos(m_hWnd, NULL, rc.left, rc arriba, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER SWP_NOACTIVATE);

}

BOOL Adjuntar(HWND hWndNew)

{

if (! ::IsWindow(hWndNew))

{

return FALSE;

}

m_hWnd = hWndNew;

devuelve VERDADERO;

}

HWND Detach()

{

HWND hWnd = m_hWnd;

m_hWnd = NULL;

devuelve hWnd;

}

HWND GetHWND()

{

return m_hWnd;

}

protegido:

HWND m_hWnd;

};

2. Definir y registrar ventanas y funciones de procesamiento de ventanas

ATOM MyRegisterWnd(TCHAR *szClsName, WNDPROC WndProc)

{WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

wcex.lpfnWndProc = WndProc;

wcex. cbClsExtra = 0;

wcex.cbWndExtra = 0;

p>

wcex.hInstance = GetModuleHandle(NULL);

wcex.hIcon = NULL;// LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TEST));

wcex.hCursor = NULL;//LoadCursor(NULL, IDC_ARROW);

wcex.hbrBackground = GetStockBrush(LTGRAY_BRUSH); //(HBRUSH)(COLOR_WINDOW + 1);

wcex.lpszMenuName = NULL ;// MAKEINTRESOURCE(IDC_TEST);

wcex.lpszClassName = szClsName;

wcex.hIconSm = NULL;// LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); p>

return RegisterClassEx(&wcex);

}

La función de procesamiento de la ventana es:

LRESULT CALLBACK CallbackImageCalibration(HWND hWnd, mensaje UINT , WPARAM wParam , LPARAM lParam)

{

// int wmId, wmEvent

PAINTSTRUCT ps;

HDC hdc; hRedBrush;

static int cxClient, cyClient;

RECT rect;

HBRUSH hbrush;

cambiar (mensaje)

{

caso WM_SIZE:

cxClient = LOWORD(lParam);

cyClient = HIWORD(lParam);

: :PostMessage( hWnd, WM_PAINT, NULL, NULL);

return 0;

case WM_ERASEBKGND:

hdc = GetDC(hWnd);//Pagar cerca atención a las variables locales Si la CC no se obtiene aquí, el borrado fallará.

hbrush = CreateSolidBrush(RGB(0, 0, 0));//Crea un nuevo pincel

GetClientRect(hWnd, &rect);

FillRect( hdc , &rect, hbrush);

ReleaseDC(hWnd, hdc);

devuelve TRUE;

caso WM_PAINT:

hdc = BeginPaint (hWnd, &ps);

m_fc.DrawriginImage(hWnd); // m_fc es la clase de corrección de imagen de ojo de pez

EndPaint(hWnd, &ps);

romper;

predeterminado:

devolver DefWindowProc(hWnd, mensaje, wParam, lParam);

}

devolver 0;

}

Registrar la ventana en el programa principal

TCHAR szClsName[256] = _T("#32775");

MyRegisterWnd ( szClsName, CallbackImageCalibration);

3. Defina los elementos en el archivo XML de la interfaz DuiLib y créelo

< /HorizontalLayout >>p>

Crea una ventana llamada Wnd1

CControlUI* CFIPFrameWnd::CreateControl(LPCTSTR pstrClassName)

{

if (_tcsicmp ( pstrClassName, _T("Wnd1")) == 0)

{

CWndUI *pUI = nuevo CWndUI;

m_hwndImageCalibration = CreateWindow(_T(" # 32775"), _T("WndImageCalibration"), WS_VISIBLE | WS_CHILD, 0, 0, 0, 0, m_PaintManager.GetPaintWindow(), (HMENU)0, NULL, NULL);

pUI-> Adjuntar (m_hwndImageCalibration);

pUI->SetVisible(true);

::ShowWindow(m_hwndImageCalibration, true);

::UpdateWindow(m_hwndImageCalibration);

devolver pUI;

}

devolver pUI;

}

4. p >

Lo que se muestra aquí es una función para la corrección de imágenes de ojo de pez.

CControlUI *pbtnWnd = m_PaintManager.FindControl(_T("wndImageCalibration"));

pbtnWnd->SetVisible(true);

//Sigue el modo de DuiLib obtiene la clase de entidad del control

CListUI* pListUI = static_cast(m_PaintManager.FindControl(_T("imageCalibrationlist")));

int nSel = pListUI-> GetCurSel ();//Obtén el de la izquierda

m_fc.fix_data = NULL;//m_fc es la clase de corrección de imagen de ojo de pez

if (nSel >= 0)

{

string_t nombre de archivo = m_imageCalibrationList.at(nSel);

Mat mat = imread(nombre de archivo);

CComboBoxUI* pComboboxUI = static_cast(m_PaintManager.FindControl(_T("calibrationMethodlist")));

int nMethod = pComboboxUI->GetCurSel();//Obtener el método de corrección, longitud, doble precisión, latitud y longitud, cilindro , etc.

m_fc.Init(mat.cols, mat.rows, CalibrationType(nMethod));

m_fc.org_mat = mat.clone();

float time = m_fc.Calibration();//Comienza a corregir la imagen de ojo de pez

CLabelUI *pLabelUI = static_cast(m_PaintManager.FindControl(_T("ImageCalibrationInfo")));

CDuiString strTmp;

strTmp.Format(_T("Tiempo de corrección de imagen: %f segundos"), tiempo);

pLabelUI->SetText(strTmp);

RECT r;

::GetWindowRect(m_hwndImageCalibration, &r);

::InvalidateRect(m_hwndImageCalibration,&r,true);//Redibujar

}

La función de redibujado está en la clase de corrección de ojo de pez, función m_fc DrawriginImage

void FisheyeCalibration::DrawriginImage(HWND hwnd)

{

if (fix_mat.data)

{

WinShowMatImage(fix_mat, hwnd);

}

}

void FisheyeCalibration::WinShowMatImage(const cv::Mat&

amp; img, HWND hwnd)

{

if (!::IsWindow(hwnd)) return;

HDC hdc = ::GetWindowDC(hwnd) ;

RECT rect;

GetWindowRect(hwnd, &rect);

RECT destRect;

destRect.left = 0; arriba = 0;

destRect.right = rect.right - rect.left;

destRect.bottom = rect.bottom - rect.top;

/ /Juzgar largo y ancho

if ( img.cols<(rect.right - rect.left) && img.rows<(rect.bottom - rect.top))

{

int tmp1 = ((rect.right - rect.left) - img.cols) / 2;

int tmp2 = ((rect.bottom - rect.top) - img .rows) / 2;

destRect.left = tmp1; destRect.right = tmp1 + img.cols;

destRect.top = tmp2; destRect.bottom = tmp2 + img. filas;

}

else

{

if (rect.bottom == rect.top) return;

relación de flotación1 = (float)(rect.right - rect.left) / (float)(rect.bottom - rect.top);

relación de float2 = (float)img.cols / ( float)img.rows;

if (ratio1 > ratio2)

{

int w = ratio2*(rect.bottom - rect.top);

int h = rect.bottom - rect.top;// ratio2*img.rows;

destRect.left = (rect.right - rect.left - w) / 2; destRect.right = (rect.right - rect.left - w) / 2 + w;

destRect.top = 0; destRect.bottom = h;

}

else

{

int w = rect.right - rect.left;// ratio1*img.cols;

int h = ( rect.right - rect.left) / ratio2;// ratio1*img.rows;

destRect.left = 0; destRect.right = w;

destRect.top = ( rect.abajo-rect.arriba-h

) / 2; destRect.bottom = (rect.bottom - rect.top - h) / 2 + h;

}

}

CvMat _img = img;

const CvArr* arr = &_img;

CvMat stub;

CvMat* imagen = cvGetMat(arr, &stub);

//Construir el encabezado BITMAPINFO

TAMAÑO tamaño = { imagen->ancho, imagen->alto };

int canales = 3;

BITMAPINFO binfo ;

memset(&binfo, 0, sizeof(binfo));

BITMAPINFOHEADER& bmih = binfo.bmiHeader;

bmih.biSize = tamaño de(BITMAPINFOHEADER);

bmih.biWidth = talla.cx;

bmih.biHeight = abs(talla.cy);

bmih.biPlanes = 1;

bmih.biBitCount = (corto sin firmar)(canales * 8);

bmih.biCompression = BI_RGB;

void* dst_ptr = 0;

HBITMAP hb = CreateDIBSection(hdc, &binfo, DIB_RGB_COLORS, &dst_ptr, 0, 0);

HDC windowdc = ::CreateCompatibleDC(hdc);

SelectObject(windowdc, hb);

p>

CvMat dst;

cvInitMatHeader(&dst, size.cy, size.cx, CV_8UC3, dst_ptr, (size.cx*canales + 3)&-4);

int origen = ((IplImage*)arr)->origen;

cvConvertImage(imagen, &dst, 1/*origen == 0 ? CV_CVTIMG_FLIP : 0*/);

// Mostrar

SetStretchBltMode(hdc, COLORONCOLOR);

StretchBlt(hdc, destRect.left+1, destRect.top+1, destRect.right - destRect. izquierda, destRect .bottom - destRect.top, windowdc, 0, 0, size.cx, size.cy, SRCCOPY);

}