12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658 |
- #include "stdafx.h"
- #include "DocScannerCap.h"
- #include "math.h"
- //template<typename T>
- //struct identity
- //{
- // typedef T type;
- //};
- //#define X(F, T) identity<T>::type& F = *reinterpret_cast<identity<T>::type*>( \
- // GetProcAddress(GetModuleHandle("user32.dll"), #F))
- //X(RegisterDeviceNotification, HDEVNOTIFY WINAPI(
- // IN HANDLE hRecipient,IN LPVOID NotificationFilter,IN DWORD Flags));
- //X(UnregisterDeviceNotification, BOOL(WINAPI *PUnregisterDeviceNotification)(IN HDEVNOTIFY Handle));
- //#undef X
- HWND g_hInnerWnd = NULL;
- HDEVNOTIFY g_hDevNotify = NULL;
- LRESULT CALLBACK CameraNotifierProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
- pFnEventFinished OnEvtFinished = &CDocScannerCap::EvtFinishedHandle;
- int GetCameraInfors(CAMERA_BUCKET& vtCameraList)
- {
- // enumerate all video capture devices
- DestoryCamereBuckets(vtCameraList);
- ICreateDevEnum *pDevEnum = NULL;
- IEnumMoniker *pEnum = NULL;
- int deviceCounter = 0;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
- reinterpret_cast<void**>(&pDevEnum));
- if (SUCCEEDED(hr)) {
- // Create an enumerator for the video capture category.
- hr = pDevEnum->CreateClassEnumerator(
- CLSID_VideoInputDeviceCategory,
- &pEnum, 0);
- if (hr == S_OK) {
- //if (!silent)printf("SETUP: Looking For Capture Devices\n");
- IMoniker *pMoniker = NULL;
- while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
- if (FAILED(hr)) {
- pMoniker->Release();
- continue; // Skip this one, maybe the next one will work.
- }
- PCAMERA_INFOR_ITEM item = new CAMERA_INFOR_ITEM();
- if(item != NULL) {
- item->Cleanup();
- // Find the description or friendly name.
- VARIANT varName;
- VariantInit(&varName);
- hr = pPropBag->Read(L"Description", &varName, 0);
- if (FAILED(hr)) {
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- }
- if (SUCCEEDED(hr)) {
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- int maxLen = sizeof(item->szDevName) - 2;
- int nLen = WrapW2A(varName, &(item->szDevName[0]), maxLen);
- VariantClear(&varName);
- }
- VARIANT varCLSID;
- VariantInit(&varCLSID);
- hr = pPropBag->Read(L"CLSID", &varCLSID, 0);
- if (SUCCEEDED(hr)) {
- int maxLen = sizeof(item->szCLSID) - 2;
- int nLen = WrapW2A(varCLSID, &(item->szCLSID[0]), maxLen);
- VariantClear(&varCLSID);
- }
- VARIANT varDevPath;
- VariantInit(&varDevPath);
- hr = pPropBag->Read(L"DevicePath", &varDevPath, 0);
- if (SUCCEEDED(hr)) {
- int maxLen = sizeof(item->szDevPath) - 2;
- int nLen = WrapW2A(varDevPath, &(item->szDevPath[0]), maxLen);
- VariantClear(&varDevPath);
- }
- VARIANT varWaveID;
- VariantInit(&varWaveID);
- hr = pPropBag->Read(L"WaveInID", &varWaveID, 0);
- if (SUCCEEDED(hr)) {
- item->uWaveInID = varWaveID.lVal;
- VariantClear(&varWaveID);
- }
- vtCameraList.push_back(item);
- }
- pPropBag->Release();
- pPropBag = NULL;
- pMoniker->Release();
- pMoniker = NULL;
- deviceCounter++;
- }
- pDevEnum->Release();
- pDevEnum = NULL;
- pEnum->Release();
- pEnum = NULL;
- }
- }
- return deviceCounter;
- }
- int IsDeviceBusy(const char* lpcszDeviceName)
- {
- LOG_FUNCTION();
- int nRet = -2;
- ICreateDevEnum *pDevEnum = NULL;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pDevEnum);
- IEnumMoniker *pEnum = NULL;
- hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
- if (SUCCEEDED(hr)) {
- // Create an enumerator for the video capture category.
- IMoniker *pMoniker = NULL;
- nRet = -1;
- while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
- IPropertyBag *pPropBag = NULL;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
- if (FAILED(hr)) {
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- continue; // Skip this one, maybe the next one will work.
- }
- VARIANT varName;
- VariantInit(&varName);
- hr = pPropBag->Read(L"Description", &varName, 0);
- if (FAILED(hr)) {
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- }
- if (SUCCEEDED(hr)) {
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- int count = 0;
- char tmp[255] = {0};
- while (varName.bstrVal[count] != 0x00 && count < 255) {
- tmp[count] = (char)varName.bstrVal[count];
- count++;
- }
- if(SUCCEEDED(hr)) {
- if(!strcmp(lpcszDeviceName, tmp)) {
- //Deal the specific device
- nRet = 0;
- LPBC* pbc = NULL;
- IBaseFilter *P_VCamTrans = NULL;
- IBaseFilter *pCap = NULL;
- CreateBindCtx(0, pbc);
- hr = pMoniker->BindToObject((IBindCtx *)pbc, 0, IID_IBaseFilter,(void **)&pCap);
-
- IGraphBuilder *m_pGB = NULL;
- IMediaControl *m_pMC = NULL;
- IVideoWindow *m_pVW = NULL;
- IMediaEventEx *m_pME = NULL;
- hr = CoCreateInstance(CLSID_FilterGraph, NULL,
- CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB);
- if (FAILED(hr)) {
- nRet = -2;
- SAFE_RELEASE_IDEV(m_pGB);
- SAFE_RELEASE_IDEV(pCap);
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- goto PEnd;
- }
- m_pGB->AddFilter(pCap, NULL);
- ICaptureGraphBuilder2 *m_pCapGB = NULL;
- hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
- CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&m_pCapGB);
- if (FAILED(hr)) {
- nRet = -2;
- SAFE_RELEASE_IDEV(m_pCapGB);
- SAFE_RELEASE_IDEV(m_pGB);
- SAFE_RELEASE_IDEV(pCap);
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- goto PEnd;
- }
- m_pCapGB->SetFiltergraph(m_pGB);
- IAMCrossbar *pXBar1 = NULL;
- hr = m_pCapGB->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pCap,
- IID_IAMCrossbar,(void **)&pXBar1);
- if (SUCCEEDED(hr)) {
- long OutputPinCount;
- long InputPinCount;
- long PinIndexRelated;
- long PhysicalType;
- long inPort = 0;
- long outPort = 0;
- pXBar1->get_PinCounts(&OutputPinCount,&InputPinCount);
- int videoBusy = 1;
- for (int i=0; i<InputPinCount; i++) {
- for (int j=0; j<OutputPinCount; j++) {
- if(S_OK == pXBar1->CanRoute(j, i)) {
- pXBar1->Route(j,i);
- m_pGB->AddFilter(pCap, L"Capture Filter");
- hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
- hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);
- hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);
- hr = m_pVW->put_Owner((OAHWND)NULL);
- hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);
- hr = m_pVW->put_Visible(OAFALSE);
- hr = m_pVW->put_AutoShow(OAFALSE);
- HRESULT innhr = m_pMC->StopWhenReady();
- if (SUCCEEDED(innhr))
- {
- videoBusy = 0;
- }
- else {
- Dbg("It works ? %d, %d", i, j);
- }
- SAFE_RELEASE_IDEV(m_pVW);
- SAFE_RELEASE_IDEV(m_pMC);
- SAFE_RELEASE_IDEV(P_VCamTrans);
- }
- }
- }
- if (videoBusy == 1)
- {
- Dbg("Test 1");
- nRet = 1; //视频设备占用
- }
- SAFE_RELEASE_IDEV(pXBar1);
- }
- else //pXBar1
- {
- m_pGB->AddFilter(pCap, L"Capture Filter");
- m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
- hr = m_pGB->QueryInterface(IID_IMediaEventEx, (void**)&m_pME);
- hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);
- hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);
- hr = m_pVW->put_Owner((OAHWND)NULL);
- hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);
- hr = m_pVW->put_Visible(OAFALSE);
- hr = m_pVW->put_AutoShow(OAFALSE);
- HRESULT innhr = m_pMC->StopWhenReady();
- if (FAILED(innhr))
- {
- Dbg("Test 2");
- nRet = 1; //视频设备占用
- }
- SAFE_RELEASE_IDEV(m_pVW);
- SAFE_RELEASE_IDEV(m_pMC);
- SAFE_RELEASE_IDEV(P_VCamTrans);
- }
- SAFE_RELEASE_IDEV(m_pCapGB);
- SAFE_RELEASE_IDEV(m_pGB);
- SAFE_RELEASE_IDEV(pCap);
- break;
- }
- }
- }
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- }
- }
- PEnd:
- SAFE_RELEASE_IDEV(pDevEnum);
- SAFE_RELEASE_IDEV(pEnum);
- Dbg("IsDeviceBusy(%s) returned %d", lpcszDeviceName, nRet);
- if(nRet != 1) {
- nRet = 0;
- }
- return nRet;
- }
- int GetCameraCount()
- {
- ICreateDevEnum *pDevEnum = NULL;
- IEnumMoniker *pEnum = NULL;
- int deviceCounter = 0;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
- reinterpret_cast<void**>(&pDevEnum));
- if (SUCCEEDED(hr)) {
- hr = pDevEnum->CreateClassEnumerator(
- CLSID_VideoInputDeviceCategory,
- &pEnum, 0);
- if(hr == S_OK){
- IMoniker *pMoniker = NULL;
- while (pEnum->Next(1, &pMoniker, NULL) == S_OK){
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
- (void**)(&pPropBag));
- if (FAILED(hr)){
- pMoniker->Release();
- continue; // Skip this one, maybe the next one will work.
- }
- pPropBag->Release();
- pPropBag = NULL;
- pMoniker->Release();
- pMoniker = NULL;
- deviceCounter++;
- }
- pEnum->Release();
- pEnum = NULL;
- }
- pDevEnum->Release();
- pDevEnum = NULL;
- }
- return deviceCounter;
- }
- int UpdateCameraInfors(CAMERA_BUCKET& vtCameraList)
- {
- int old_count = vtCameraList.size();
- if(old_count > 0) {
- DestoryCamereBuckets(vtCameraList);
- }
- GetCameraInfors(vtCameraList);
- return old_count;
- }
- int ExclusiveCameraBuckes(const CAMERA_BUCKET& lhs, const CAMERA_BUCKET& rhs, CAMERA_BUCKET& diff)
- {
- int count = 0;
- const size_t l_size = lhs.size();
- const size_t r_size = rhs.size();
- if(!diff.empty()) {
- DestoryCamereBuckets(diff);
- }
- //Is it necessary to sort before doing comparation job ?
- if(l_size > r_size) {
- for(CAMERA_BUCKET_CITER citer=lhs.cbegin(); citer!=lhs.cend(); ++citer) {
- auto aim = std::find_if(rhs.cbegin(), rhs.cend(),
- [citer](PCAMERA_INFOR_ITEM const item){
- return !strcmp(item->szDevPath, (*citer)->szDevPath);
- });
- if(aim == rhs.cend()) {
- PCAMERA_INFOR_ITEM item = new CAMERA_INFOR_ITEM();
- if(item != NULL) {
- item->Copy((*citer));
- diff.push_back(item);
- count++;
- }
- }
- }
- } else if(l_size < r_size) {
- for(CAMERA_BUCKET_CITER citer=rhs.cbegin(); citer!=rhs.cend(); ++citer) {
- auto aim = std::find_if(lhs.cbegin(), lhs.cend(), [citer](PCAMERA_INFOR_ITEM const item){
- return !strcmp(item->szDevPath, (*citer)->szDevPath);
- });
- if(aim == lhs.cend()) {
- PCAMERA_INFOR_ITEM item = new CAMERA_INFOR_ITEM();
- if(item != NULL) {
- item->Copy((*citer));
- diff.push_back(item);
- count++;
- }
- }
- }
- }
- return count;
- }
- void DisplayCameraInfos(const CAMERA_BUCKET& vtCameraList)
- {
- Dbg("Cameralist:(%d)", vtCameraList.size());
- for(CAMERA_BUCKET_CITER it=vtCameraList.cbegin(); it!=vtCameraList.cend(); ++it) {
- if(*it) {
- (*it)->Display();
- }else {
- LOG_ASSERT(!"Empty elememt occurs !!");
- }
- }
- }
- void OnMouseTrace(int evt, int x, int y, int flags, void* param = NULL);
- const Scalar RED = Scalar(0,0,255);
- const Scalar PINK = Scalar(230,130,255);
- const Scalar BLUE = Scalar(255,0,0);
- const Scalar LIGHTBLUE = Scalar(255,255,160);
- const Scalar GREEN = Scalar(0,255,0);
- const Scalar BLACK = Scalar(0, 0, 0);
- const Scalar ERROR_GRAY = Scalar(205, 205, 205);
- const int WAITKEY_TIME = 30;
- const DWORD ERROR_CONTINUE_MILLSEC = 3000;
- const int ERROR_CONTINUE_TIMES = ERROR_CONTINUE_MILLSEC / WAITKEY_TIME;
- CDocScannerCap::CDocScannerCap(CPortableScannerFSM* pFSM)
- :m_videoID(-1)
- ,m_hrCoInited(S_FALSE)
- ,m_defWnd(NULL)
- ,m_dwErrCode(ERROR_SUCCESS)
- ,m_hPreviewPro(NULL)
- ,m_fPreviewing(false)
- ,m_colorMode(COLORFUL)
- ,m_roiMode(ROI_DEFAULT)
- ,m_roiRate(1.0f)
- ,m_bHide(FALSE)
- ,m_winSize(DR_X, DR_Y, DR_W, DR_H)
- ,rectStatus(NOT_SET)
- ,m_pFSM(pFSM)
- ,m_bHSPSType(false)
- {
- m_hrCoInited = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- }
- CDocScannerCap::~CDocScannerCap(void)
- {
- LOG_FUNCTION();
- #if 1
- //let VideoCapture object invoke release at destructor.
- _cleanup(false);
- RequestQueueCleanup();
- //Would meet confict ?
- Dbg("before destroyAllWindows...");
- destroyAllWindows();
- Dbg("after destroyAllWindows...");
- #endif
- if(m_hrCoInited == S_OK) {
- CoUninitialize();
- }
- }
- void CDocScannerCap::Test()
- {
- // cv::VideoCapture videoCap(0);
- // if(!videoCap.isOpened())
- // {
- // return;
- // }
- // cv::Mat edges;
- //#define WINDOWS_TITLE "edges"
- // cv::namedWindow(WINDOWS_TITLE);
- // moveWindow(WINDOWS_TITLE, 0, 0);
- // setWindowProperty(WINDOWS_TITLE, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
- // //HWND hWin = FindWindow(NULL, WINDOWS_TITLE);
- // HWND hWin = (HWND)cvGetWindowHandle(WINDOWS_TITLE);
- // DWORD dwFlag = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER;
- // dwFlag &= ~SWP_NOSIZE;
- // if(hWin == NULL)
- // {
- // LOG_TRACE("Find %s window handle faiiled, GLE=%u", WINDOWS_TITLE, GetLastError());
- // }
- // SetWindowPos(hWin, HWND_NOTOPMOST, 128, 128, edges.cols, edges.rows, dwFlag);
- // //Bordorless
- // SetWindowLong(hWin, GWL_STYLE, GetWindowLong(hWin, GWL_EXSTYLE) | WS_EX_TOPMOST | WS_EX_LAYERED);
- // SetLayeredWindowAttributes(hWin, RGB(255,255,255), 0, LWA_COLORKEY);
- // SetWindowLong(hWin, GWL_STYLE, GetWindowLong(hWin, GWL_EXSTYLE)
- // & (~WS_CAPTION)
- // & (~WS_BORDER)
- // & (~WS_THICKFRAME));
- // ShowWindow(hWin, SW_SHOW);
- // for(;;)
- // {
- // cv::Mat cameraFrame;
- // videoCap >> cameraFrame ;
- // imshow(WINDOWS_TITLE, cameraFrame);
- // if(cv::waitKey(30) >= 0) {
- // cameraFrame.release();
- // destroyWindow(WINDOWS_TITLE);
- // break;
- // }
- // }
- }
- bool CDocScannerCap::InitHwndForNotify()
- {
- static char szWindowClass[] = "Win32_DocScannerCap";
- static char szTitle[] = "Win32 Document Scanner Notificer";
- //get instance of current program (self)
- HINSTANCE hInstance = GetModuleHandle (NULL);
- char szPcName[MAX_PATH] = {0};
- DWORD nSize = sizeof(szPcName);
- GetComputerName(szPcName, &nSize);
- WNDCLASSEX wcex;
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = CameraNotifierProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.lpszMenuName = NULL;
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
- if (!RegisterClassEx(&wcex))
- {
- return false;
- }
- HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
- if (!hWnd)
- {
- return false;
- }
- ShowWindow(hWnd, SW_HIDE);
- UpdateWindow(hWnd);
- g_hInnerWnd = hWnd;
- return true;
- }
- bool CDocScannerCap::RegisterVideoNotify()
- {
- DEV_BROADCAST_DEVICEINTERFACE filterData;
- ZeroMemory(&filterData, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
- filterData.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
- filterData.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
- filterData.dbcc_classguid = AM_KSCATEGORY_VIDEO;
- g_hDevNotify = RegisterDeviceNotification(g_hInnerWnd, &filterData, DEVICE_NOTIFY_WINDOW_HANDLE);
- if (g_hDevNotify == NULL) {
- return false;
- }
- return true;
- }
- bool CDocScannerCap::UnRegisterVideoNotify()
- {
- if (g_hDevNotify != NULL) {
- UnregisterDeviceNotification(g_hDevNotify);
- g_hDevNotify = NULL;
- }
- return true;
- }
- bool CDocScannerCap::Open(unsigned int idx)
- {
- if(m_cvCap.isOpened()) {
- _cleanup();
- }
- //the method first call release to close alreay opened file or camera
- m_cvCap.open(idx);
- if(!m_cvCap.isOpened()) {
- Dbg("open failed:");
- m_dwErrCode = ERROR_OPEN_FAILED;
- winName.clear();
- return false;
- }
- _setProperty();
- {
- CAMERA_INFOR_ITEM item;
- if(GetSpecificedCamInfor(idx, &item) > 0) {
- _setDevName(item.szDevName);
- winName = cv::String(DEFAULT_MAT_WINDOW_NAME) + "-" + devName;
- }else {
- CHAR szDevIndex[128] = {0};
- sprintf_s(szDevIndex, "%s-%d", DEFAULT_MAT_WINDOW_NAME, idx);
- winName = szDevIndex;
- _setDevName("");
- }
- }
- m_videoID = idx;
- m_dwErrCode = ERROR_SUCCESS;
- return true;
- }
- void CDocScannerCap::_setProperty()
- {
- //设置为不一样的分辨率,会出现耗时,1.5s 长城
- //SetResoultionRatio(1920, 1080);
- }
- bool CDocScannerCap::OpenCamera(LPCTSTR lpcszDev)
- {
- if(lpcszDev == NULL) {
- m_dwErrCode = ERROR_INVALID_PARAMETER;
- return false;
- }
- const int camId = _getCamIDByDevName(lpcszDev);
- if(camId < 0) {
- m_dwErrCode = ERROR_FILE_NOT_FOUND;
- Dbg("not found camera id.");
- return false;
- }
- //const int nRes = IsDeviceBusy(lpcszDev);
- //if(nRes) {
- // if(nRes == -2) {
- // m_dwErrCode = ERROR_INVALID_ACCESS;
- // } else if(nRes == -1) {
- // m_dwErrCode = ERROR_FILE_NOT_FOUND;
- // } else if(nRes == 1) {
- // m_dwErrCode = ERROR_DEVICE_IN_USE;
- // } else {
- // m_dwErrCode = ERROR_BAD_ENVIRONMENT;
- // }
- // return false;
- //}
- if(Open(camId))
- {
- if(devName.empty())
- _setDevName(lpcszDev);
- return true;
- }
- return false;
- }
- bool CDocScannerCap::ScanImage(const char* lpcszFilePath)
- {
- if(!m_fPreviewing) {
- Dbg("Request scaning without in previewing.");
- m_dwErrCode = ERROR_INVALID_ENVIRONMENT;
- return false;
- }
- if(lpcszFilePath == NULL) {
- m_dwErrCode = ERROR_INVALID_PARAMETER;
- return false;
- }
- char szFileName[MAX_PATH] = {0};
- int len = strlen(lpcszFilePath);
- if(len == 0) {
- _combineFileName(szFileName, MAX_PATH);
- cv::String strFileName("C:\\");
- strFileName += szFileName;
- strFileName += ".jpg";
- strcpy_s(szFileName, strFileName.c_str());
- }
- else {
- strcpy_s(szFileName, lpcszFilePath);
- }
- len = strlen(szFileName);
- if(len == 0) {
- m_dwErrCode = ERROR_INVALID_PARAMETER;
- return false;
- }
- RequestEventPtr item = CreateRequestEvent(EVTCODE_SCAN);
- if(!item) {
- Dbg("CreateRequestEvent failed");
- m_dwErrCode = ERROR_RESOURCE_FAILED;
- return false;
- }
- item->evtData = (CHAR*)malloc(sizeof(char)*(len+1));
- if(item->evtData == NULL) {
- Dbg("malloc failed");
- m_dwErrCode = ERROR_RESOURCE_FAILED;
- delete item;
- return false;
- }
- memset(item->evtData, 0, sizeof(char)*(len+1));
- strcpy_s(item->evtData, sizeof(char)*(len+1), szFileName);
- item->dwDataLen = len+1;
- PostIntoRequestQueue(&item);
- Dbg("WaitForResponse...");
- int nRes = WaitForResponse(EVTCODE_SCAN, 30*1000);
- Dbg("WaitForResponse returned: 0x%02x", nRes);
- if(nRes >= EVTSTATUS_ERROR_MASK) {
- }
- else if(nRes == EVTSTATUS_DONE_SUCC) {
- Dbg("Scan succ: %d[%s]", ExistsFileA(szFileName), szFileName);
- //Mat picture = imread(szFileName);
- //if(!picture.empty()) {
- // namedWindow("show-img");
- // imshow("show-img", picture);
- //}
- //else {
- // Dbg("picture is empty!!");
- //}
- }
- return true;
- }
- bool CDocScannerCap::CloseCamera()
- {
- _cleanup();
- m_dwErrCode = ERROR_SUCCESS;
- return true;
- }
- bool CDocScannerCap::StartPreview()
- {
- if(!_isVal()){
- m_dwErrCode = ERROR_INVALID_ENVIRONMENT;
- return false;
- }
- if(m_fPreviewing) {
- m_dwErrCode = SCHED_E_ALREADY_RUNNING;
- return false;
- }
- m_hPreviewPro = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0,
- CDocScannerCap::WndPreviewDlgProc, this,
- CREATE_SUSPENDED,
- NULL));
- if(m_hPreviewPro == NULL || m_hPreviewPro == INVALID_HANDLE_VALUE)
- {
- m_hPreviewPro = NULL;
- m_dwErrCode = E_HANDLE;
- Dbg("Create WndPreviewDlgProc thread failed");
- return false;
- }
- m_fPreviewing = true;
- if(ResumeThread(m_hPreviewPro) == (DWORD)-1) {
- Dbg("ResumeThread failed, GLE=%u", GetLastError());
- m_dwErrCode = E_UNEXPECTED;
- m_fPreviewing = false;
- CloseHandle(m_hPreviewPro);
- m_hPreviewPro = NULL;
- return false;
- }
- m_dwErrCode = ERROR_SUCCESS;
- return true;
- }
- bool CDocScannerCap::TerminatePreview()
- {
- m_dwErrCode = ERROR_SUCCESS;
- if(m_fPreviewing) {
- m_dwErrCode = E_UNEXPECTED;
- m_tpStopPreview = true;
- //30 seconds to timeout?
- Dbg("Set StopPreivew flag true, waitting...");
- DWORD dwResult = WaitForSingleObject(m_hPreviewPro, 30 * 1000);
- if(dwResult == WAIT_OBJECT_0) {
- Dbg("Wait succ.");
- //assert(m_fPreviewing == false);
- CloseHandle(m_hPreviewPro);
- m_hPreviewPro = NULL;
- m_dwErrCode = ERROR_SUCCESS;
- return true;
- }else if(dwResult == WAIT_TIMEOUT) {
- Dbg("Wait succ timeout: %d", m_fPreviewing);
- if(!m_fPreviewing) {
- CloseHandle(m_hPreviewPro);
- m_hPreviewPro = NULL;
- m_dwErrCode = ERROR_SUCCESS;
- return true;
- }
- m_dwErrCode = WAIT_TIMEOUT;
- }
- else {
- Dbg("WaitForSingleObject failed returned: %u.", dwResult);
- m_dwErrCode = dwResult;
- }
- }
- return (m_dwErrCode == ERROR_SUCCESS);
- }
- bool CDocScannerCap::_initWindow(bool fShown)
- {
- if(m_defWnd) {
- _destroyWindow();
- }
- //TODO: Identify the window name to unique.
- DWORD wdFlags = WINDOW_NORMAL;
- namedWindow(winName, wdFlags);
- m_defWnd = FindWindow(NULL, winName.c_str());
- if(m_defWnd == NULL) {
- destroyWindow(winName);
- m_dwErrCode = ERROR_INVALID_WINDOW_HANDLE;
- Dbg("Find %s window handle faiiled, GLE=%u", winName.c_str(), GetLastError());
- return false;
- }
- DWORD dwFlag = fShown ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
- BOOL bRet = ::SetWindowPos(m_defWnd, HWND_TOPMOST,
- m_winSize.x, m_winSize.y, m_winSize.width, m_winSize.height, dwFlag);
- Dbg("WinSize(%d): %d, %d, %d, %d", bRet, m_winSize.x, m_winSize.y, m_winSize.width, m_winSize.height);
- if(bRet) { m_bHide = !fShown; }
- m_dwErrCode = ERROR_SUCCESS;
- rectStatus = NOT_SET;
- return true;
- }
- void CDocScannerCap::_destroyWindow()
- {
- LOG_FUNCTION();
- if(!m_cmFrame.empty()) {
- m_cmFrame.release();
- }
- if(m_defWnd) {
- Dbg("before destroyWindow with %s", winName.c_str());
- destroyWindow(winName);
- Dbg("after destroyWindow with %s", winName.c_str());
- m_defWnd = NULL;
- m_bHide = FALSE;
- }
- return;
- }
- size_t CDocScannerCap::_combineFileName(char* szFnBuf, size_t sizeLen)
- {
- if(sizeLen == 0 || szFnBuf == NULL) {
- return 0;
- }
- memset(szFnBuf, 0, sizeof(char)*sizeLen);
- SYSTEMTIME st;
- GetLocalTime(&st);
- sprintf_s(szFnBuf, sizeLen, "%04d%02d%02d%02d%02d%02d.jpg", st.wYear, st.wMonth, st.wDay,
- st.wHour, st.wMinute, st.wSecond);
- return strlen(szFnBuf);
- }
- UINT WINAPI CDocScannerCap::WndPreviewDlgProc(PVOID param)
- {
- CDocScannerCap *pCap = reinterpret_cast<CDocScannerCap*>(param);
- if(pCap == NULL) {
- Dbg("WndPreviewDlgProc::praram is invalid(empty)");
- return UINT(-1);
- }
- return (UINT)(pCap->_executePreview());
- }
- void CDocScannerCap::EvtFinishedHandle(USHORT evtCode, UCHAR result, UINT checksum)
- {
- Dbg("EvtCode:%d, result:%d, checksum:%d", evtCode, result, checksum);
- }
- void CDocScannerCap::SetResoultionRatio(int width, int height, int nframes /*= -1*/)
- {
- Dbg("before: width=%d, height=%d , nframes=%d", (int)m_cvCap.get(CAP_PROP_FRAME_WIDTH),
- (int)m_cvCap.get(CAP_PROP_FRAME_HEIGHT), (int)m_cvCap.get(CAP_PROP_FRAME_COUNT));
- m_cvCap.set(CV_CAP_PROP_FRAME_WIDTH, width);
- m_cvCap.set(CV_CAP_PROP_FRAME_HEIGHT, height);
- Dbg("after: width=%d, height=%d , nframes=%d", (int)m_cvCap.get(CAP_PROP_FRAME_WIDTH),
- (int)m_cvCap.get(CAP_PROP_FRAME_HEIGHT), (int)m_cvCap.get(CAP_PROP_FRAME_COUNT));
- //m_cvCap.set(CAP_PROP_CONVERT_RGB, 0);
- }
- void CDocScannerCap::_setMouseCallback()
- {
- cvSetMouseCallback(winName.c_str(), OnMouseTrace, this);
- }
- void CDocScannerCap::MouseClick(int event, int x, int y, int flags)
- {
- //static Rect origin;
- if(event == CV_EVENT_LBUTTONDOWN) {
- //if(rectStatus == NOT_SET)
- {
- //Dbg("CV_EVENT_LBUTTONDOWN");
- rectStatus = IN_PROCESS;
- rect = Rect(x, y, 0, 0);
- //origin = rect;
- }
- } else if(event == CV_EVENT_MOUSEMOVE) {
- if(rectStatus == IN_PROCESS) {
- rect = Rect(Point(rect.x, rect.y), Point(x,y));
- //rect.x = MIN(origin.x, x);
- //rect.y = MIN(origin.y, y);
- //rect.width = abs(origin.x - x);
- //rect.height = abs(origin.y - y);
- //Dbg("CV_EVENT_MOUSEMOVE: %d,%d,%d,%d TID(%u)", rect.x, rect.y, rect.width, rect.height, GetCurrentThreadId());
- }
- }else if(event == CV_EVENT_LBUTTONUP) {
- if(rectStatus == IN_PROCESS) {
- if(rect.height == 0 || rect.width == 0) {
- Dbg("CV_EVENT_LBUTTONUP::Zero Area");
- rectStatus = NOT_SET;
- return;
- }
- rect = Rect(Point(rect.x, rect.y), Point(x,y));
- Dbg("CV_EVENT_LBUTTONUP");
- rectStatus = SET;
- }
- }
- }
- void CDocScannerCap::_setResizeArea(float ratio)
- {
- //m_cmFrame.at<Vec3b>(m_cmFrame.cols / 2, m_cmFrame.rows / 2)[0] = 0;
- //m_cmFrame.at<Vec3b>(m_cmFrame.cols / 2, m_cmFrame.rows / 2)[1] = 0;
- //m_cmFrame.at<Vec3b>(m_cmFrame.cols / 2, m_cmFrame.rows / 2)[2] = 255;
- //putText(m_cmFrame, "Hello", Point(m_cmFrame.cols/2, m_cmFrame.rows/2), 0, 0.7, Scalar(255, 0, 0));
- Rect area((1-ratio)/2*m_cmFrame.cols, (1-ratio)/2*m_cmFrame.rows, ratio*m_cmFrame.cols, ratio*m_cmFrame.rows);
- //Mat mask;
- //mask.create(m_cmFrame.size(), CV_8UC1);
- //mask.setTo( GC_BGD );
- //(mask(area)).setTo( Scalar(GC_PR_FGD));
- //Mat binMask;
- //if( binMask.empty() || binMask.rows != mask.rows || binMask.cols != mask.cols )
- // binMask.create(mask.size(), CV_8UC1 );
- //binMask = mask & 1;
- //m_cmFrame.copyTo(res, binMask);
- //WRITE_INFO_PARAM("w, h: %d, %d", m_cmFrame.cols, m_cmFrame.rows);
- //WRITE_INFO_PARAM("x, y, w, h: %d, %d, %d, %d", area.x, area.y, area.width, area.height);
- Mat roi = m_cmFrame(area);
- Mat res;
- res.create(roi.rows, roi.cols, m_cmFrame.type());
- roi.copyTo(res);
- //WRITE_INFO_PARAM("2 w, h: %d, %d", res.cols, res.rows);
- m_cmFrame.release();
- m_cmFrame = res;
- //rectangle(m_cmFrame, Point(area.x, area.y),
- // Point(area.x + area.width, area.y + area.height),
- // RED, rectangle_thickness);
- }
- void CDocScannerCap::_setInterestArea()
- {
- if(rectStatus == IN_PROCESS || rectStatus == SET) {
- Rect area(rect);
- //Dbg("rect: %d, %d, %d, %d", rect.x, rect.y, rect.width, rect.height);
- int suffix_x = rect.x - drawableRect.x;
- int suffix_y = rect.y - drawableRect.y;
- area.x = suffix_x > 0 ? rect.x : drawableRect.x;
- area.y = suffix_y > 0 ? rect.y : drawableRect.y;
- suffix_x = suffix_x > 0 ? suffix_x : 0;
- suffix_y = suffix_y > 0 ? suffix_y : 0;
- area.width = min(rect.width, drawableRect.width-suffix_x-rectangle_thickness);
- area.height = min(rect.height, drawableRect.height-suffix_y-rectangle_thickness);
- rectangle(m_cmFrame, Point(area.x, area.y),
- Point(area.x + area.width, area.y + area.height),
- GREEN, rectangle_thickness);
- assert(m_cmFrame.data);
- //Dbg("drawableRect: %d, %d, %d, %d", drawableRect.x, drawableRect.y, drawableRect.width, drawableRect.height);
- const CvScalar colorMask = cvScalarAll(-52);
- Mat res = Mat::ones(m_cmFrame.size(), CV_8UC1)*255;
- //Dbg("area: %d, %d, %d, %d", area.x, area.y, area.width, area.height);
- res(area).setTo(0);
- cv::add(m_cmFrame, (const cv::Scalar&)colorMask, m_cmFrame, res, m_cmFrame.type());
- rect = area;
- }
- }
- bool CDocScannerCap::_executePreview()
- {
- _initWindow(true);
- m_tpStopPreview = false;
- _setMouseCallback();
- if (GetWindowLong(m_defWnd, GWL_STYLE) & WS_POPUP) {
- SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
- }
- int eOccurTimes = 0, eClosedTimes = 0;
- DWORD dwEStartTick = 0;
- char szFileName[MAX_PATH] = {0};
- for(;;)
- {
- m_cvCap >> m_cmFrame;
- if(!m_cmFrame.data) {
- continue;
- }
- Mat gray = m_cmFrame.clone();
- cvtColor(m_cmFrame, gray, CV_BGR2GRAY);
- if(IsColorAbnormal(&IplImage(gray))) {
- IplImage* inner = &IplImage(gray);
- int B = CV_IMAGE_ELEM(inner, unsigned char, inner->height/2, (inner->width/2)*3+0);
- int G = CV_IMAGE_ELEM(inner, unsigned char, inner->height/2, (inner->width/2)*3+1);
- int R = CV_IMAGE_ELEM(inner, unsigned char, inner->height/2, (inner->width/2)*3+2);
- if(B == G && G == R && R == 205) {
- if(eOccurTimes == 0) {
- eOccurTimes++;
- Dbg("Wow! the scanner has problem");
- dwEStartTick = GetTickCount();
-
- }else if(eOccurTimes != -1) {
- eOccurTimes++;
- if(eOccurTimes >= ERROR_CONTINUE_TIMES
- || GetTickCount() > dwEStartTick + ERROR_CONTINUE_MILLSEC) {
- Dbg("Send Reset Event !! %d", eOccurTimes);
- eOccurTimes = -1;
- SetResetEvent();
- }
- }
- }else if(eOccurTimes != 0){
- eOccurTimes = 0;
- }
-
- if(B == G && G == R && B == 0) {
- if(eClosedTimes == 0) {
- Dbg("Eh, maybe forget to scratch the scanner");
- eClosedTimes = 1;
- }
-
- }else if(eClosedTimes != 0){
- Dbg("Ok, you achieve it");
- eClosedTimes = 0;
- }
-
- } else {
-
- if(eOccurTimes != 0 && eOccurTimes != -1) {
- eOccurTimes = 0;
- }
- if(eClosedTimes != 0){
- Dbg("Ok, you achieve it");
- eClosedTimes = 0;
- }
- }
- gray.release();
- if(m_roiMode != ROI_DEFAULT && m_bHSPSType) {
- _setResizeArea(m_roiRate);
- }
- if(m_colorMode == GRAY) {
- cvtColor(m_cmFrame, m_cmFrame, CV_BGR2GRAY);
- }
- Mat origin = m_cmFrame.clone();
- int cols = 0, rows = 0;
- {//填充边框以适应宽度
- Size origin_size = m_cmFrame.size();
- if(1.0*m_winSize.width / m_winSize.height > 1) {
- int aimWidth = (int)(1.0*origin_size.height*(1.0*m_winSize.width / m_winSize.height));
- if(aimWidth > origin_size.width) {
- cols = (aimWidth-origin_size.width) / 2;
- }else if(aimWidth < origin_size.width) {
- int aimHeigth = (int)(1.0*origin_size.width*(1.0*m_winSize.height / m_winSize.width));
- assert(aimHeigth >= origin_size.height);
- rows = (aimHeigth-origin_size.height) / 2;
- }
- }else if(1.0*m_winSize.width / m_winSize.height < 1) {
- int aimHeigth = (int)(1.0*origin_size.width*(1.0*m_winSize.height / m_winSize.width));
- if(aimHeigth > origin_size.height) {
- rows = (aimHeigth-origin_size.height) / 2;
- }else if(aimHeigth < origin_size.height) {
- int aimWidth = (int)(1.0*origin_size.height*(1.0*m_winSize.width / m_winSize.height));
- assert(aimWidth >= origin_size.width);
- cols = (aimWidth-origin_size.width) / 2;
- }
- }
- }
- if(cols > 0 || rows > 0) {
- copyMakeBorder(m_cmFrame, m_cmFrame, rows, rows, cols, cols, BORDER_CONSTANT, BLACK);
- }
- //Dbg("m_winSize: %d, %d", m_winSize.width, m_winSize.height);
- //Dbg("m_cmFrame: %d, %d", m_cmFrame.cols, m_cmFrame.rows);
- drawableRect.x = cols;
- drawableRect.width = origin.cols;
- drawableRect.y = rows;
- drawableRect.height = origin.rows;
- Mat picture = m_cmFrame.clone();
- _setInterestArea();
- imshow(winName, m_cmFrame);
- char keyCode = cvWaitKey(WAITKEY_TIME);
- //if(keyCode == 27) {
- // Dbg("ESC key press event recv.");
- // break;
- //}
- RequestEventPtr evtPtr = GetRequest();
- if(evtPtr) {
- Dbg("0x%02x event recv.", evtPtr->evtCode);
- switch(evtPtr->evtCode)
- {
- case EVTCODE_SCAN:
- {
- assert(evtPtr->valType == RequestEvent::ReqLen);
- assert(evtPtr->dwDataLen > 0 && evtPtr->evtData);
- char szFileName[MAX_PATH+1] = {0};
- memcpy_s(szFileName, MAX_PATH*sizeof(char),
- evtPtr->evtData, sizeof(char)*evtPtr->dwDataLen);
- try
- {
- cv::Mat testMat;
- if(rectStatus == SET && (rect.width != 0 && rect.height != 0)) {
- Mat result(picture, rect);
- //imwrite(szFileName, result);
- Dbg("ScanImage@1: %s %d", szFileName, result.size());
- testMat = result.clone();
-
- } else {
- //imwrite(szFileName, origin);
- Dbg("ScanImage@2: %s %d", szFileName, origin.size());
- testMat = origin.clone();
- }
- ImageWriteUntil(szFileName, testMat);
- //cv::Mat destMat;
- /*int compatRate = MatResize(testMat, destMat, 100);
- compatRate = compatRate > 0 ? compatRate + 1: 100;*/
- //const int compatRate = 90;
- //Dbg("set compress rate: %d", compatRate);
- //vector<int> comprressionParams;
- //comprressionParams.push_back(CV_IMWRITE_JPEG_QUALITY);
- //comprressionParams.push_back(compatRate);
- //default one
- //comprressionParams.push_back(IMWRITE_JPEG_OPTIMIZE);
- //comprressionParams.push_back(1);
- //imwrite(szFileName, testMat, comprressionParams);
- //Resize(szFileName, GetFileSize(szFileName), compatRate);
- evtPtr->evtStatus = EVTSTATUS_DONE_SUCC;
- }
- catch(cv::Exception& ex)
- {
- Dbg("exception converting image to jpeg: %s", ex.what());
- evtPtr->evtStatus = EVTSTATUS_DONE_FAIL;
- }
- evtPtr->OnAnswer();
- }
- break;
- default:
- {
- }
- break;
- }
- }
- if(m_tpStopPreview) {
- Dbg("Stop previewing event recv.");
- break;
- }
- }
- SetThreadExecutionState(ES_CONTINUOUS);
- _destroyWindow();
- m_fPreviewing = false;
- return true;
- }
- int CDocScannerCap::GetSpecificedCamInfor(const int camID, PCAMERA_INFOR_ITEM info)
- {
- if(info == NULL) {
- return -2;
- }
- info->Cleanup();
- // Create the System Device Enumerator.
- ICreateDevEnum *pSysDevEnum = NULL;
- HRESULT hr = CoCreateInstance(
- CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
- IID_ICreateDevEnum, (void **)&pSysDevEnum);
- if (FAILED(hr)) {
- return -1;
- }
- BOOL done = false;
- int deviceCounter = 0;
- // Obtain a class enumerator for the video input category.
- IEnumMoniker *pEnumCat = NULL;
- hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
- if (hr == S_OK) {
- // Enumerate the monikers.
- IMoniker *pMoniker = NULL;
- ULONG cFetched;
- while ((pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) && (!done)) {
- if(deviceCounter == camID) {
- // Bind the first moniker to an object
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
- if (SUCCEEDED(hr)) {
- // To retrieve the filter's friendly name, do the following:
- VARIANT varName;
- VariantInit(&varName);
- hr = pPropBag->Read(L"Description", &varName, 0);
- if (FAILED(hr)) {
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- }
- if (SUCCEEDED(hr)) {
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- int maxLen = sizeof(info->szDevName) - 2;
- int nLen = WrapW2A(varName, &(info->szDevName[0]), maxLen);
- VariantClear(&varName);
- }
- VARIANT varCLSID;
- VariantInit(&varCLSID);
- hr = pPropBag->Read(L"CLSID", &varCLSID, 0);
- if (SUCCEEDED(hr)) {
- int maxLen = sizeof(info->szCLSID) - 2;
- int nLen = WrapW2A(varCLSID, &(info->szCLSID[0]), maxLen);
- VariantClear(&varCLSID);
- }
- VARIANT varDevPath;
- VariantInit(&varDevPath);
- hr = pPropBag->Read(L"DevicePath", &varDevPath, 0);
- if (SUCCEEDED(hr)) {
- int maxLen = sizeof(info->szDevPath) - 2;
- int nLen = WrapW2A(varDevPath, &(info->szDevPath[0]), maxLen);
- VariantClear(&varDevPath);
- }
- VARIANT varWaveID;
- VariantInit(&varWaveID);
- hr = pPropBag->Read(L"WaveInID", &varWaveID, 0);
- if (SUCCEEDED(hr)) {
- info->uWaveInID = varWaveID.lVal;
- VariantClear(&varWaveID);
- }
- pPropBag->Release();
- pPropBag = NULL;
- pMoniker->Release();
- pMoniker = NULL;
- done = TRUE;
- }
- }
- deviceCounter++;
- }
- pEnumCat->Release();
- pEnumCat = NULL;
- }
- pSysDevEnum->Release();
- pSysDevEnum = NULL;
- if (done) {
- return 1;
- }
- return 0;
- }
- int CDocScannerCap::_getCamIDByDevName(LPCTSTR lpcszDevName)
- {
- if (lpcszDevName == NULL || strlen(lpcszDevName) == 0) {
- return -2;
- }
- ICreateDevEnum *pDevEnum = NULL;
- IEnumMoniker *pEnum = NULL;
- int deviceCounter = 0;
- int aimID = -1;
- bool done = false;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
- reinterpret_cast<void**>(&pDevEnum));
- if (SUCCEEDED(hr)) {
- // Create an enumerator for the video capture category.
- hr = pDevEnum->CreateClassEnumerator(
- CLSID_VideoInputDeviceCategory,
- &pEnum, 0);
- if(hr == S_OK) {
- IMoniker *pMoniker = NULL;
- while (pEnum->Next(1, &pMoniker, NULL) == S_OK && (!done)) {
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
- (void**)(&pPropBag));
- if (FAILED(hr)){
- pMoniker->Release();
- continue; // Skip this one, maybe the next one will work.
- }
- // Find the description or friendly name.
- VARIANT varName;
- VariantInit(&varName);
- hr = pPropBag->Read(L"Description", &varName, 0);
- if (FAILED(hr)) hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- if (SUCCEEDED(hr)){
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- char szDevName[MAX_PATH + 2] = {0};
- int count = 0;
- while( varName.bstrVal[count] != 0x00 && count < MAX_PATH) {
- szDevName[count] = (char)varName.bstrVal[count];
- count++;
- }
- szDevName[count] = 0;
- if(strcmp(szDevName, lpcszDevName) == 0) {
- done = true;
- aimID = deviceCounter;
- }
- }
- pPropBag->Release();
- pPropBag = NULL;
- pMoniker->Release();
- pMoniker = NULL;
- deviceCounter++;
- }
- pDevEnum->Release();
- pDevEnum = NULL;
- pEnum->Release();
- pEnum = NULL;
- }
- }
- return aimID;
- }
- bool CDocScannerCap::IsColorAbnormal(IplImage* src)
- {
- const int threshold = 3;
- const int width = src->width;
- const int height = src->height;
- int imax = 0, imin = 255;
- uchar *content = (uchar*)src->imageData;
- int step = src->widthStep/sizeof(uchar);
- for (int i=0; i<height; ++i) {
- for(int j=0; j<width; ++j) {
- int term = (int)content[i*step+j];
- if(term > imax) {
- imax = term;
- }
- if(term < imin) {
- imin = term;
- }
- }
- }
- if(imax - imin < threshold) {
- return true;
- }
- return false;
- }
- bool CDocScannerCap::IsFrameFuzzy(IplImage* data)
- {
- //图片每行字节数及高
- int width=data->widthStep;
- int height=data->height;
- ushort* sobelTable = new ushort[width*height];
- memset(sobelTable, 0, width*height*sizeof(ushort));
- int i, j, mul;
- //指向图像首地址
- uchar* udata = (uchar*)data->imageData;
- for(i = 1, mul = i*width; i < height - 1; i++, mul += width) {
- for(j = 1; j < width - 1; j++) {
- sobelTable[mul+j]=abs(udata[mul+j-width-1] + 2*udata[mul+j-1] + udata[mul+j-1+width] -\
- udata[mul+j+1-width] - 2*udata[mul+j+1] - udata[mul+j+width+1]);
- }
- }
- for(i = 1, mul = i*width; i < height - 1; i++, mul += width) {
- for(j = 1; j < width - 1; j++) {
- if(sobelTable[mul+j] < 50 || sobelTable[mul+j] <= sobelTable[mul+j-1] ||\
- sobelTable[mul+j] <= sobelTable[mul+j+1]) sobelTable[mul+j] = 0;
- }
- }
- int totLen = 0;
- int totCount = 1;
- uchar suddenThre = 50;
- uchar sameThre = 3;
- //遍历图片
- for(i = 1, mul = i*width; i < height - 1; i++, mul += width) {
- for(j = 1; j < width - 1; j++) {
- if(sobelTable[mul+j]) {
- int count = 0;
- uchar tmpThre = 5;
- uchar max = udata[mul+j] > udata[mul+j-1] ? 0 : 1;
- for(int t = j; t > 0; t--) {
- count++;
- if(abs(udata[mul+t] - udata[mul+t-1]) > suddenThre) {
- break;
- }
- if(max && udata[mul+t] > udata[mul+t-1]) {
- break;
- }
- if(!max && udata[mul+t] < udata[mul+t-1]) {
- break;
- }
- int tmp = 0;
- for(int s = t; s > 0; s--) {
- if(abs(udata[mul+t] - udata[mul+s]) < sameThre) {
- tmp++;
- if(tmp > tmpThre) {
- break;
- }
- }
- else {
- break;
- }
- }
- if(tmp > tmpThre) break;
- }
- max = udata[mul+j] > udata[mul+j+1] ? 0 : 1;
- for(int t = j; t < width; t++) {
- count++;
- if(abs(udata[mul+t] - udata[mul+t+1]) > suddenThre) {
- break;
- }
- if(max && udata[mul+t] > udata[mul+t+1]) {
- break;
- }
- if(!max && udata[mul+t] < udata[mul+t+1]) {
- break;
- }
- int tmp = 0;
- for(int s = t; s < width; s++) {
- if(abs(udata[mul+t] - udata[mul+s]) < sameThre) {
- tmp++;
- if(tmp > tmpThre) {
- break;
- }
- }
- else {
- break;
- }
- }
- if(tmp > tmpThre) {
- break;
- }
- }
- max = udata[mul+j] > udata[mul+j+1] ? 0 : 1;
- for(int t = j; t < width; t++) {
- count++;
- if(abs(udata[mul+t] - udata[mul+t+1]) > suddenThre) {
- break;
- }
- if(max && udata[mul+t] > udata[mul+t+1]) {
- break;
- }
- if(!max && udata[mul+t] < udata[mul+t+1]) {
- break;
- }
- int tmp = 0;
- for(int s = t; s < width; s++) {
- if(abs(udata[mul+t] - udata[mul+s]) < sameThre) {
- tmp++;
- if(tmp > tmpThre) {
- break;
- }
- }
- else {
- break;
- }
- }
- if(tmp > tmpThre) {
- break;
- }
- }
- count--;
- totCount++;
- totLen += count;
- }
- }
- }
- //模糊度
- float result = (float)totLen/totCount;
- delete[] sobelTable;
- if(result > 5) {
- return true;
- }
- return false;
- }
- bool CDocScannerCap::ResetCamera()
- {
- if(!_isVal() && m_videoID == -1) {
- Dbg("Nothing to do with ResetCamera(%d)", m_videoID);
- return true;
- }
- bool fPreview = m_fPreviewing;
- BOOL bHide = m_bHide;
- if(m_fPreviewing) {
- TerminatePreview();
- do {
- Sleep(100);
- } while (m_fPreviewing);
- }
- if(m_cvCap.isOpened()) {
- m_cvCap.release();
- }
- CAMERA_INFOR_ITEM item;
- if(GetSpecificedCamInfor(m_videoID, &item) <= 0) {
- m_dwErrCode = ERROR_FILE_NOT_FOUND;
- _cleanup();
- return true;
- }
- int nRes = IsDeviceBusy(item.szDevName);
- if(nRes) {
- if(nRes == -2) {
- m_dwErrCode = ERROR_INVALID_ACCESS;
- } else if(nRes == -1) {
- m_dwErrCode = ERROR_FILE_NOT_FOUND;
- } else if(nRes == 1) {
- m_dwErrCode = ERROR_DEVICE_IN_USE;
- } else {
- m_dwErrCode = ERROR_BAD_ENVIRONMENT;
- }
- _cleanup();
- return true;
- }
- m_cvCap.open(m_videoID);
- if(!m_cvCap.isOpened()) {
- _cleanup();
- return false;
- }
- _destroyWindow();
- winName = cv::String(DEFAULT_MAT_WINDOW_NAME) + "-" + item.szDevName;
- _setDevName(item.szDevName);
- m_dwErrCode = ERROR_SUCCESS;
- //SetWinShown(m_hideMode != 0 ? false : true);
- if(fPreview && !StartPreview()) {
- Dbg("StartPreview failed");
- return true;
- }else if(fPreview && bHide) {
- SetWinShown(false);
- }
- return true;
- }
- int CDocScannerCap::MatResize(const cv::Mat& src, cv::Mat& dest, int quantity)
- {
- const int aim_size = 1*1024*1024;
- std::vector<int> params;
- params.push_back(cv::IMWRITE_JPEG_QUALITY);
- params.push_back(quantity);
- std::vector<unsigned char> buff;
- cv::imencode(".jpg", src, buff, params);
- Dbg("after buffer: size: %d, with quantity: %d", buff.size(), quantity);
- dest = cv::imdecode(buff, CV_LOAD_IMAGE_COLOR);
- if(buff.size() > aim_size)
- return (int)(aim_size * 1.2f / buff.size() * 100);
- return 0;
- }
- DWORD CDocScannerCap::GetFileSize(LPCTSTR srcFilePath)
- {
- FILE* fHandle = fopen(srcFilePath, "rb");
- if(!fHandle)
- return -1;
- fseek(fHandle, 0, SEEK_END);
- DWORD fileSize = ftell(fHandle);
- Dbg("get the file size: %lu", fileSize);
- fclose(fHandle);
- return fileSize;
- }
- int CDocScannerCap::ImageWriteUntil(LPCTSTR srcFilePath, const cv::Mat& src)
- {
- const int aim_size = 1*1024*1024;
- int compatRates[] = {95, 90, 85, 80, 70, 60, 50, 40, 30, 20, 15};
- for(int i=0; i<sizeof(compatRates)/sizeof(compatRates[0]); ++i)
- {
- const int compatRate = compatRates[i];
- Dbg("set compress rate: %d", compatRate);
- vector<int> comprressionParams;
- comprressionParams.push_back(CV_IMWRITE_JPEG_QUALITY);
- comprressionParams.push_back(compatRate);
- try
- {
- imwrite(srcFilePath, src, comprressionParams);
- } catch(cv::Exception& ex)
- {
- Dbg("exception converting image to jpeg: %s", ex.what());
- return -1;
- }
- Sleep(50);
- const auto fileSize = GetFileSize(srcFilePath);
- if(fileSize == (DWORD)-1)
- return -1;
- if(fileSize <= aim_size)
- return 0;
- }
- return 1;
- }
- int CDocScannerCap::Resize(LPCTSTR srcFilePath, DWORD dwSrcFileSize, int compressRate)
- {
- const int aim_size = 1*1024*1024;
- if(dwSrcFileSize == -1 || aim_size >= dwSrcFileSize)
- return 0;
- cv::Mat src = cv::imread(srcFilePath);
- if(src.empty())
- return -1;
- float rate = sqrt(aim_size * 1.0f / dwSrcFileSize);
- Dbg("rate: %f", rate);
- int width = static_cast<int>(src.cols*rate);
- int height = static_cast<int>(src.rows*rate);
- cv::Mat dest;
- resize(src, dest, cv::Size(width, height));
- vector<int> comprressionParams;
- comprressionParams.push_back(CV_IMWRITE_JPEG_QUALITY);
- comprressionParams.push_back(compressRate);
- imwrite(srcFilePath, dest, comprressionParams);
- FILE* fHandle = fopen(srcFilePath, "rb");
- fseek(fHandle, 0, SEEK_END);
- long fileSize = ftell(fHandle);
- fclose(fHandle);
- Dbg("get the resize file size: %ld", fileSize);
- return 1;
- }
- LRESULT CALLBACK CameraNotifierProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- if (message == WM_DEVICECHANGE) {
- if (DBT_DEVICEARRIVAL != wParam && DBT_DEVICEREMOVECOMPLETE != wParam) {
- return TRUE;
- }
- PDEV_BROADCAST_HDR pdbh = (PDEV_BROADCAST_HDR)lParam;
- if (pdbh->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE) {
- return TRUE;
- }
- PDEV_BROADCAST_DEVICEINTERFACE pdbi = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
- if (pdbi->dbcc_classguid == AM_KSCATEGORY_VIDEO) {
- if (DBT_DEVICEARRIVAL == wParam) {
- printf("receive AM_KSCATEGORY_VIDEO change add \n");
- } else if (DBT_DEVICEREMOVECOMPLETE == wParam) {
- printf("receive AM_KSCATEGORY_VIDEO change remove \n");
- }
- }
- return TRUE;
- }
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- void OnMouseTrace(int event, int x, int y, int flags, void* param /*= NULL*/)
- {
- CDocScannerCap* pCap = reinterpret_cast<CDocScannerCap*>(param);
- if(pCap == NULL) {
- Dbg("OnMouseTest::param is NULL!");
- return;
- }
- pCap->MouseClick(event, x, y, flags);
- }
|