Skip to content
GBG Documents & Biometrics Documentation

Displaying RAW and ROI images (C++ example)

GBG provides the CppAdvancedExample to demonstrate how to implement RAW and ROI functionality and to display RAW and ROI images. The CppAdvancedExample C++ project is based on the CPPSimpleExample C++ project. The CppAdvancedExample project displays RAW and ROI images according to selected regions.

Use the following DocumentRegionAdded defined event to get all regions information:

DISP_FUNCTION_ID(CMainDialog, "DocumentRegionAdded", DISPID_DOCUMENTREGIONADDED, OnDocumentRegionAdded, VT_EMPTY, VTS_DISPATCH)
void CMainDialog::OnDocumentRegionAdded(IDocumentRegionEventArgs *pArgs)
{
CComPtr<IDocumentRegion> pDocumentRegion;
if (SUCCEEDED(pArgs->get_Region(&pDocumentRegion))) //Get document region pointer
{
BSTR vtRegionName;
pDocumentRegion->get_Name(&vtRegionName); //Get region name
Rectangle nodeRect;
pDocumentRegion->get_Rectangle(&nodeRect); //Get region rectangle
//==Insert Tree Item with region name
TV_INSERTSTRUCT tvInsertStruct;
tvInsertStruct.hParent = NULL;
tvInsertStruct.hInsertAfter = TVI_SORT;
std::wstring name_wstr = L" ...";
const WCHAR* nameWchar = name_wstr.c_str()+ _bstr_t(vtRegionName);
tvInsertStruct.item.pszText = LPWSTR(nameWchar);
tvInsertStruct.item.mask = TVIF_TEXT | TVIF_IMAGE;
tvInsertStruct.item.iImage = 0;
HTREEITEM hItem = treeRegionsView.InsertItem(&tvInsertStruct);
//==Insert Tree sub Item with rectangle points.
TV_INSERTSTRUCT tvInsertStruct2;
tvInsertStruct2.hParent = hItem;
tvInsertStruct2.hInsertAfter = TVI_LAST;
std::wstring disply_wstr =L"...{X=" +std::to_wstring(nodeRect.X) + L",Y="+
std::to_wstring(nodeRect.Y) +
L",Width=" +std::to_wstring(nodeRect.Width)+L",Hight=" +
std::to_wstring(nodeRect.Height);
const WCHAR* dispWchar = disply_wstr.c_str();
tvInsertStruct2.item.pszText = LPWSTR(dispWchar);
tvInsertStruct2.item.mask = TVIF_TEXT | TVIF_IMAGE;
tvInsertStruct2.item.iImage = 2;
HTREEITEM hRegionItem = treeRegionsView.InsertItem(&tvInsertStruct2);
//====Store the pointer as ItemData at the tree.
IUnknown* pUnk = NULL;
HRESULT hr = pDocumentRegion->QueryInterface(IID_PPV_ARGS(&pUnk));
treeRegionsView.SetItemData(hItem, reinterpret_cast<DWORD_PTR> (pUnk)); DeleteObject(pUnk);
}
}

This section gets all regions information and stores them in the Regions tree. Each region displays the Region Name and Region rectangle.

This section gets all regions information and stores them in the Regions tree. Each region displays the

Regions Display tree view item selection (Click Event )

ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &CMainDialog::onTreeViewRegionsItemSelect)

void CMainDialog::onTreeViewRegionsItemSelect(NMHDR *pNMHDR, LRESULT *pResult)

{
//Get selected tree item text
HTREEITEM hItem = treeRegionsView.GetSelectedItem();
CComPtr<IDocumentRegion> region;
//Get the Stored pointer to the region.
DWORD_PTR pRegionObj = treeRegionsView.GetItemData(hItem);
//==With region Pointer when clicked the parent item the region is displayed
region = (IDocumentRegion*)pRegionObj;
HTREEITEM hParent = treeRegionsView.GetParentItem(hItem);
if (region && hParent==NULL)
{
setRegion(region);
}
else {
treeRegionsView.SetItemImage(hItem, 2, 2);
treeRegionsView.Invalidate();
}
}
//Displays the region at the m_ClipImageTab Tab
void CMainDialog::setRegion(CComPtr<IDocumentRegion> region)
{
int last_cure_sel= m_ClipImageTab.GetCurSel();
RemoveAllClipImageTabs();
//Raw Tab
CComPtr<IBitmap> pBMap;
region->get_Bitmap(&pBMap);
Rectangle regionRect;
region->get_Rectangle(&regionRect);
CString strImageName = CString("Raw");
// Create RAW image tab with the RAW bitmap.
TCITEM tcItem = { 0 };
tcItem.mask = TCIF_PARAM;
tcItem.pszText = strImageName.GetBuffer();
CImageWnd* pImageWnd = new CImageWnd(pBMap);
CRect rcWindow;
m_ClipImageTab.GetWindowRect(&rcWindow);
ScreenToClient(&rcWindow);
m_ClipImageTab.AdjustRect(FALSE, &rcWindow);
pImageWnd->Create(NULL, NULL, WS_CHILD, rcWindow, this, 0);
tcItem.mask |= TCIF_PARAM;
tcItem.lParam = (LPARAM)pImageWnd;
m_ClipImageTab.SetItem(1, &tcItem);

The following section gets region references by using the get_References method, gets reference images by using the get_images method from the image collection, and crops the region rectangle from the image.

Section titled “The following section gets region references by using the get_References method, gets reference images by using the get_images method from the image collection, and crops the region rectangle from the image.”
//ROI TAB
CComPtr<IDocumentObjectReferences> PtrDocRef;
HRESULT result = region->get_References(&PtrDocRef);//Get the References.
if (SUCCEEDED(result) && PtrDocRef != NULL) {
CComPtr<IDocumentObjectCollection> imageColection;
CComPtr<IDocumentImage> pDocumentImage;
result = PtrDocRef->get_Images(&imageColection);//Get the Image collection.
long count = 0;
result = imageColection->get_Count(&count);//Get the imagecollection count.
if (SUCCEEDED(result) && imageColection != NULL)
{
CComPtr<IDispatch> imagePtr;
result = imageColection->get_Item(0,&imagePtr);//Imageitem pointer
if (SUCCEEDED(result))
{
pDocumentImage = imagePtr;
CComPtr<IBitmap> pBitmapROI;
pDocumentImage->get_Bitmap(&pBitmapROI); //Get the bitmap
Rectangle rect;
region->get_Rectangle(&rect);
CString strImageName = CString("ROI");
// Create ROI image tab.
TCITEM tcItemROI = { 0 };
tcItemROI.mask = TCIF_TEXT;
tcItemROI.pszText = strImageName.GetBuffer();
//Get the handle to the bitmap..
HBITMAP hBitmap2;
if (pBitmapROI!=NULL && SUCCEEDED(pBitmapROI->GetHbitmap((long*)&hBitmap2)))
{
BITMAP bm;
PAINTSTRUCT ps;
HWND hwnd = GetDlgItem(IDC_CLIP_IMAGE_TAB)->m_hWnd;
HDC hdc = ::BeginPaint(hwnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HGDIOBJ hbmOld = SelectObject(hdcMem, hBitmap2);
GetObject(hBitmap2, sizeof(bm), &bm);
CImage image;
image.Create(rect.Width, rect.Height, 32);
HDC imageHDC = image.GetDC();
//Crop the region rectangle from the image and display it.
::SetStretchBltMode(imageHDC, HALFTONE);
::StretchBlt(imageHDC, 0, 0, rect.Width, rect.Height, hdcMem, rect.X, rect.Y,
rect.Width, rect.Height, SRCCOPY | CAPTUREBLT);
//Release image handels...
image.ReleaseDC();
DeleteDC(hdcMem);
DeleteDC(hdc);
::EndPaint(hwnd, &ps);
// ROI tab .
CImageWnd* pImageWndROI = new CImageWnd(pBitmapROI);
CRect rcWindowROI;
m_ClipImageTab.GetWindowRect(&rcWindowROI);
ScreenToClient(&rcWindowROI);
pImageWndROI = new CImageWnd(image);
m_ClipImageTab.AdjustRect(FALSE, &rcWindowROI);
pImageWndROI->Create(NULL, NULL, WS_CHILD, rcWindowROI, this, 0);
tcItemROI.mask |= TCIF_PARAM;
tcItemROI.lParam = ((LPARAM)pImageWndROI);
m_ClipImageTab.SetItem(0, &tcItemROI);
if (last_cure_sel != 1)
{
m_ClipImageTab.SetCurSel(0);
pImageWndROI->ShowWindow(SW_SHOW);
}
//Release images.
image.Destroy();
DeleteObject(hBitmap2);
DeleteObject(hbmOld);
}
}
}
}

The ROI tab displays the cropped image. The RAW tab displays the raw bitmap.

The ROI tab displays the cropped image. The RAW tab displays the raw bitmap.

The ROI tab displays the cropped image. The RAW tab displays the raw bitmap.

The OnDocumentImageTabSelChange event is fired when the user selects the ROI or RAW tab.

ON_NOTIFY(TCN_SELCHANGE, IDC_DOCUMENT_IMAGE_TAB, &CMainDialog::OnDocumentImageTabSelChange)
/**
* Handles when the currently selected tab has changed and displays the appropriate
* document image.
*/
void CMainDialog::OnDocumentImageTabSelChange(NMHDR *pNMHDR, LRESULT *pResult)
{
int nIndex = m_ImageTabCtrl.GetCurSel();
for (int i = 0; i < m_ImageTabCtrl.GetItemCount(); i++)
{
TCITEM tcItem = { 0 };
tcItem.mask = TCIF_PARAM;
m_ImageTabCtrl.GetItem(i, &tcItem);
CImageWnd *pImageWnd = (CImageWnd*)tcItem.lParam;
pImageWnd->ShowWindow((nIndex == i) ? SW_SHOW : SW_HIDE);
DeleteObject(pImageWnd);
}
}

The OnDocumentFieldChanged event is used to get all fields and images of the fields information.

DISP_FUNCTION_ID(CMainDialog, "DocumentFieldChanged", DISPID_DOCUMENTFIELDCHANGED, OnDocumentFieldChanged, VT_EMPTY, VTS_DISPATCH)
/**
* Handles the DocumentFieldChanged event. Populates the UI with the data from
* the most recent Document transaction.
*/
void CMainDialog::OnDocumentFieldChanged(IDocumentFieldEventArgs *pArgs)
{
int itemCount = m_ListCtlFields.GetItemCount();
InsertField(pArgs, itemCount);
}
void CMainDialog::InsertField(IDocumentFieldEventArgs *pArgs,int index)
{
CComPtr<IDocumentField> pDocumentField;
if (SUCCEEDED(pArgs->get_Field(&pDocumentField)))
{
CComBSTR bsName;
pDocumentField->get_Name(&bsName);
VARIANT bsValue;
HRESULT hr = pDocumentField->get_Value(&bsValue);
CComBSTR bsdescription;
pDocumentField->get_Description(&bsdescription);
DocumentDataSource bsdataSource;
pDocumentField->get_DataSource(&bsdataSource);
m_ListCtlFields.InsertItem(index, _T(""));
m_ListCtlFields.SetItemText(index, 0, bsName);
m_ListCtlFields.SetItemText(index, 1, GetValueAsString(bsValue));
m_ListCtlFields.SetItemText(index, 2, bsdescription);
m_ListCtlFields.SetItemText(index, 3, ToDocumentDataSource(bsdataSource));
// Set Field ItemData
if (pDocumentField != NULL)
IUnknown* pUnk = NULL;
HRESULT hr = pDocumentField->QueryInterface(IID_PPV_ARGS(&pUnk));
m_ListCtlFields.SetItemData(index, reinterpret_cast<DWORD_PTR> (pUnk));
DeleteObject(pUnk);
}
//=======UPDATE at the Boigraphic fields...
if (bsName == _T("Full Name"))
{ m_NameStatic.SetWindowText(CString(bsValue));
}
else if (bsName == _T("Sex"))
{ CString sexString = CString(bsValue);
CString sex = CString("");
if (sexString.MakeLower().Find(_T("m")) >= 0) sex = "Male";
else if (sexString.MakeLower().Find(_T("f")) >= 0) sex = "Female";
m_Gender.SetWindowText(sex);
}
else if (bsName == _T("Expiration Date"))
{ if (IsValidDate(CString(bsValue)))
m_ExpirationDate.SetWindowText(CString(bsValue));
}
else if (bsName == _T("Birth Date"))
{
if (IsValidDate(CString(bsValue)))
m_BirthDateStatic.SetWindowText(CString(bsValue));
}
else if (bsName == _T("Issue Date"))
{
if (IsValidDate(CString(bsValue)))
m_IssueDate.SetWindowText(CString(bsValue));
}
else if (bsName == _T("Document Number"))
{
m_DocumentNumber.SetWindowText(CString(bsValue));
}
}
}

Select ListCtlFields to display the selected field on the ROI and RAW tabs:

ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CMainDialog::onListFieldItemSelect)

Select ListCtlFields to display the selected field on the ROI and RAW tabs

ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CMainDialog::onListFieldItemSelect)
void CMainDialog::onListFieldItemSelect(NMHDR *pNMHDR, LRESULT *pResult)
{
int m_SelCount = m_ListCtlFields.GetSelectedCount();
if (m_SelCount == 1)
{
int dgvRow = -1;
dgvRow = m_ListCtlFields.GetNextItem(dgvRow, LVNI_SELECTED);
DWORD_PTR ptrItem = m_ListCtlFields.GetItemData(dgvRow);
CString s_value = m_ListCtlFields.GetItemText(dgvRow,1);
CString s_Name = m_ListCtlFields.GetItemText(dgvRow, 0);
if (ptrItem == NULL) {
RemoveAllClipImageTabs();
return;
}
//Get Field ItemData
CComPtr<IDocumentField> pDocumentField = (IDocumentField*)ptrItem;
CComPtr<IDocumentRegion> pDocumentRegion = getRegionFromField(pDocumentField);
CComPtr<IDocumentRegion> region;
region = (IDocumentRegion*)pDocumentRegion;
if (region != NULL)
{
setRegion(region);
}
else {
RemoveAllClipImageTabs();
}
}
}
// Get Region From Field
CComPtr<IDocumentRegion> CMainDialog::getRegionFromField(CComPtr<IDocumentField> pDocumentField)
{
CComPtr<IDocumentRegion> pDocumentRegion = getRegionFromFieldDirect(pDocumentField);
if (pDocumentRegion != NULL)
return pDocumentRegion;
pDocumentRegion = getRegionFromFieldRecursive(pDocumentField);
return pDocumentRegion;
}
// Get Region From Field Direct
CComPtr<IDocumentRegion> CMainDialog::getRegionFromFieldDirect(CComPtr<IDocumentField> pDocumentField)
{
CComPtr<IDocumentRegion> pDocumentRegion = NULL;
// Get field references
CComPtr<IDocumentObjectReferences> PtrDocRef;
HRESULT result = pDocumentField->get_References(&PtrDocRef);
if (SUCCEEDED(result) && PtrDocRef != NULL)
return getRegionFromReferences(PtrDocRef);
return NULL;
}
//Get Region From Field Recursive
CComPtr<IDocumentRegion> CMainDialog::getRegionFromFieldRecursive(CComPtr<IDocumentField> pDocumentField)
{
CComPtr<IDocumentRegion> pDocumentRegion = NULL;
// Get field references
CComPtr<IDocumentObjectReferences> PtrDocRef;
HRESULT result = pDocumentField->get_References(&PtrDocRef);
if (SUCCEEDED(result) && PtrDocRef != NULL)
{
// Get all fields
CComPtr<IDocumentObjectCollection> pDocumentObjectFields;
result = PtrDocRef->get_Fields(&pDocumentObjectFields);
if (SUCCEEDED(result) && pDocumentObjectFields != NULL)
{
long f_count = 0;
pDocumentObjectFields->get_Count(&f_count);
for (int iField = 0; iField < f_count; iField++)
{
CComPtr<IDispatch> fieldPtr;
result = pDocumentObjectFields->get_Item(iField, &fieldPtr);
if (fieldPtr != NULL)
{
CComPtr<IDocumentField> pDocumentFieldNext;
pDocumentFieldNext = fieldPtr;
pDocumentRegion = getRegionFromFieldDirect(pDocumentFieldNext);
if (pDocumentRegion != NULL)
return pDocumentRegion;
pDocumentRegion = getRegionFromFieldRecursive(pDocumentFieldNext);
if (pDocumentRegion != NULL)
return pDocumentRegion;
}
}
}
}
return NULL;
}

Alerts descriptions

The OnDocumentAlertAdded event is used to get all Alerts information.

DISP_FUNCTION_ID(CMainDialog, "DocumentAlertAdded", DISPID_DOCUMENTALERTADDED, OnDocumentAlertAdded, VT_EMPTY, VTS_DISPATCH)
void CMainDialog::OnDocumentAlertAdded(IDocumentAlertEventArgs *pArgs)
{
CComPtr<IDocumentAlert> pDocumentAlert;
if (SUCCEEDED(pArgs->get_Alert(&pDocumentAlert)))
{
InsertAlert(pDocumentAlert);
}
}
void CMainDialog::InsertAlert(CComPtr<IDocumentAlert> pDocumentAlert)
{
CComBSTR bsName;
pDocumentAlert->get_Name(&bsName);
CComBSTR bsdescription;
pDocumentAlert->get_Description(&bsdescription);
AuthenticationResult AuthoResult;
pDocumentAlert->get_Result(&AuthoResult);
int itemCount = m_AlertsList.GetItemCount();
m_AlertsList.InsertItem(itemCount, _T(""), static_cast<int>(AuthoResult));
m_AlertsList.SetImageList(&m_ImageList, LVSIL_SMALL);
CComBSTR bsDisplayName;
pDocumentAlert->get_DisplayName(&bsDisplayName);
m_AlertsList.SetItemText(itemCount, 1, bsDisplayName);
m_AlertsList.SetItemText(itemCount, 2, bsdescription);
// Set Alert ItemData
if (pDocumentAlert != NULL)
{
IUnknown* pUnk = NULL;
HRESULT hr = pDocumentAlert->QueryInterface(IID_PPV_ARGS(&pUnk));
m_AlertsList.SetItemData(itemCount, reinterpret_cast<DWORD_PTR> (pUnk));
DeleteObject(pUnk);
}
}

The selected field is displayed on the ROI and RAW tabs.

The selected field is displayed on the ROI and RAW tabs.

ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, &CMainDialog::onListAlertItemSelect)
void CMainDialog::onListAlertItemSelect(NMHDR *pNMHDR, LRESULT *pResult)
{
int m_SelCount = m_AlertsList.GetSelectedCount();
if (m_SelCount == 1)
{
int dgvRow = -1;
dgvRow = m_AlertsList.GetNextItem(dgvRow, LVNI_SELECTED);
DWORD_PTR ptrItem = m_AlertsList.GetItemData(dgvRow);
CString s_value = m_AlertsList.GetItemText(dgvRow, 1);
CString s_Name = m_AlertsList.GetItemText(dgvRow, 0);
if (ptrItem == NULL) {
RemoveAllClipImageTabs();
return;
}
//Get Alert ItemData
CComPtr<IDocumentAlert> pDocumentAlert = (IDocumentAlert*)ptrItem;
CComPtr<IDocumentRegion> pDocumentRegion = getRegionFromAlert(pDocumentAlert);
CComPtr<IDocumentRegion> region;
region = (IDocumentRegion*)pDocumentRegion;
if (region != NULL)
{ setRegion(region);
}
else {
RemoveAllClipImageTabs();
}
}
}
CComPtr<IDocumentRegion> CMainDialog::getRegionFromAlert(CComPtr<IDocumentAlert> pDocumentAlert)
{
CComPtr<IDocumentRegion> pDocumentRegion = getRegionFromAlertDirect(pDocumentAlert);
if (pDocumentRegion != NULL)
return pDocumentRegion;
pDocumentRegion = getRegionFromAlertRecursive(pDocumentAlert);
return pDocumentRegion;
}
CComPtr<IDocumentRegion> CMainDialog::getRegionFromAlertDirect(CComPtr<IDocumentAlert> pDocumentAlert)
{
CComPtr<IDocumentRegion> pDocumentRegion = NULL;
// Get field references
CComPtr<IDocumentObjectReferences> PtrDocRef;
HRESULT result = pDocumentAlert->get_References(&PtrDocRef);
if (SUCCEEDED(result) && PtrDocRef != NULL)
return getRegionFromReferences(PtrDocRef);
return NULL;
}
CComPtr<IDocumentRegion> CMainDialog::getRegionFromAlertRecursive(CComPtr<IDocumentAlert> pDocumentAlert)
{
CComPtr<IDocumentRegion> pDocumentRegion = NULL;
// Get alert references
CComPtr<IDocumentObjectReferences> PtrDocRef;
HRESULT result = pDocumentAlert->get_References(&PtrDocRef);
if (SUCCEEDED(result) && PtrDocRef != NULL)
{ // Get all fields
CComPtr<IDocumentObjectCollection> pDocumentObjectFields;
result = PtrDocRef->get_Fields(&pDocumentObjectFields);
if (SUCCEEDED(result) && pDocumentObjectFields != NULL)
{
long f_count = 0;
pDocumentObjectFields->get_Count(&f_count);
for (int iField = 0; iField < f_count; iField++)
{
CComPtr<IDispatch> fieldPtr;
result = pDocumentObjectFields->get_Item(iField, &fieldPtr);
if (fieldPtr != NULL)
{
CComPtr<IDocumentField> pDocumentFieldNext;
pDocumentFieldNext = fieldPtr;
pDocumentRegion = getRegionFromField(pDocumentFieldNext);
if (pDocumentRegion != NULL)
return pDocumentRegion;
}
}
}
}
return NULL;
}