天天看點

用MFC做一個圖檔浏覽器

這個工程做得很簡潔 OpenCV+MFC的圖檔浏覽器

首先我的圖檔都是以數字命名的,是以查找起來有規律

用MFC做一個圖檔浏覽器
用MFC做一個圖檔浏覽器

定義全局變量

定義為全局變量是因為需要在多處通路這些變量

using namespace std;
using namespace cv;
std::vector <CString>  imgNames;//用來儲存圖檔的名字
CString tempstr;
int tempNum;
vector<int>Pname_Num;
CString d, e;
int flag = 0;
string str, str2;
Mat img, img2;           

打開檔案夾路徑,并顯示前2張圖檔

void CAnnotationDlg::OnBnClickedPicpath()
{
	// TODO: 在此添加控件通知處理程式代碼
	CString m_strFileOut = _T("");  //初始化适應Unicode

	TCHAR szSelected[MAX_PATH];//用來存放檔案夾路徑  

	BROWSEINFO bi;

	LPITEMIDLIST pidl;

	bi.hwndOwner = this->m_hWnd;

	bi.pidlRoot = NULL;

	bi.pszDisplayName = szSelected;

	bi.lpszTitle = _T("選擇輸出檔案路徑");

	bi.ulFlags = BIF_RETURNONLYFSDIRS;

	bi.lpfn = NULL;

	bi.lParam = NULL;

	bi.iImage = NULL;

	if ((pidl = SHBrowseForFolder(&bi)) != NULL)

	{

		if (SUCCEEDED(SHGetPathFromIDList(pidl, szSelected))) //得到檔案夾的全路徑,不要的話,隻得本檔案夾名  

		{

			m_strFileOut = szSelected;  	//獲得檔案夾的全路徑

		}

	}
	SetDlgItemText(IDC_EDIT1, m_strFileOut);
	flag = 0;
	USES_CONVERSION;
	char* fileName = T2A(m_strFileOut);//讀取需要分離的圖檔的路徑CString->char*
	imgNames.clear();
	Pname_Num.clear();
	readImgNamefromFile(fileName, imgNames);//讀入圖檔名字到數組	
	for (int j = 0; j < imgNames.size(); j++)//找到圖檔名字,截取.字尾之前的數字并轉為int
	{		
		tempstr = imgNames[j].Mid(0, imgNames[j].Find(_T(".")));//得到0 1 25 666 8956 等等數字,還是CString類型		
		tempNum = _ttoi(tempstr);//CString->int		
		Pname_Num.push_back(tempNum);//把得到的int值壓入容器
	}
	//sort(Pname_Num.begin(), Pname_Num.end());//因為CString讀入後排序了,0,1,10,100這種,合成圖檔要先把順序轉回來	
	//sort(Pname_Num.begin(), Pname_Num.end());
	//vector<int>bb;
	//using namespace std;
	sort(Pname_Num.begin(), Pname_Num.end());
	
	d.Format(_T("%d"), Pname_Num[0]);//int->CString
	e.Format(_T("%d"), Pname_Num[1]);
	string str = CT2A(m_strFileOut + _T("\\") + d + _T(".jpg"));
	string str2 = CT2A(m_strFileOut + _T("\\") + e + _T(".jpg"));
	
	
	img = imread(str);//讀入圖檔
	img2 = imread(str2);
	//imshow("1",img);//imshow用于測試是否讀入成功
	ShowMatImage(img, IDC_piCtrl1);
	ShowMatImage(img2, IDC_piCtrl2);
	SetDlgItemText(IDC_EDIT2, m_strFileOut + _T("\\") + d + _T(".jpg"));
	SetDlgItemText(IDC_EDIT3, m_strFileOut + _T("\\") +e + _T(".jpg"));
}           

顯示下一張圖檔

void CAnnotationDlg::OnBnClickedNext()
{
	// TODO: 在此添加控件通知處理程式代碼
	GetDlgItem(IDC_piCtrl2)->ShowWindow(TRUE);
	CString PicPath;
	GetDlgItemText(IDC_EDIT1, PicPath);		
	flag = flag + 2;
	if (flag == Pname_Num.size())
	{
		MessageBox(_T("已讀取到最後一張圖檔"), _T("提示"), MB_ICONINFORMATION);		
		flag = flag - 2;
	}
	else if (Pname_Num.size() - flag == 1)

	{
		d.Format(_T("%d"), flag);
		str = CT2A(PicPath + _T("\\") + d + _T(".jpg"));
		img = imread(str);//讀入圖檔
		ShowMatImage(img, IDC_piCtrl1);
		SetDlgItemText(IDC_EDIT2, PicPath + _T("\\") + d + _T(".jpg"));
		SetDlgItemText(IDC_EDIT3,  _T(" "));
		/*CRect Rect;
		(this->GetDlgItem(IDC_piCtrl2))->GetClientRect(&Rect);
		GetDC()->FillSolidRect(&Rect, RGB(240, 240, 240));*/
		GetDlgItem(IDC_piCtrl2)->ShowWindow(FALSE);
		MessageBox(_T("已讀取到最後一張圖檔"), _T("提示"), MB_ICONINFORMATION);
		flag = flag - 2;
	}

	/*else if (flag - Pname_Num.size() >= 1)
	{
		MessageBox(_T("已讀取到最後一張圖檔"), _T("提示"), MB_ICONINFORMATION);
		flag = flag - 2;
	}*/	
	else
	
	{
		d.Format(_T("%d"), flag);
		e.Format(_T("%d"), flag + 1);
		str = CT2A(PicPath + _T("\\") + d + _T(".jpg"));
		str2 = CT2A(PicPath + _T("\\") + e + _T(".jpg"));
		img = imread(str);//讀入圖檔
		img2 = imread(str2);
		ShowMatImage(img, IDC_piCtrl1);
		ShowMatImage(img2, IDC_piCtrl2);
		SetDlgItemText(IDC_EDIT2, PicPath + _T("\\") + d + _T(".jpg"));
		SetDlgItemText(IDC_EDIT3, PicPath + _T("\\") + e + _T(".jpg"));
	}	
}           

顯示上一張圖檔

void CAnnotationDlg::OnBnClickedLast()
{
	// TODO: 在此添加控件通知處理程式代碼
	GetDlgItem(IDC_piCtrl2)->ShowWindow(TRUE);
	CString PicPath;
	GetDlgItemText(IDC_EDIT1, PicPath);
	flag = flag- 2;

	if (flag == -2)
	{
		MessageBox(_T("已讀取到第一張圖檔"), _T("提示"), MB_ICONINFORMATION);
		//GetDlgItem(IDC_Next)->EnableWindow(FALSE);//IDC_XXX為你想變灰的按鈕的ID 
		flag = flag+ 2;
	}
	else if (flag == -1)

	{
		d.Format(_T("%d"), flag+1);
		str = CT2A(PicPath + _T("\\") + d + _T(".jpg"));
		img = imread(str);//讀入圖檔
		ShowMatImage(img, IDC_piCtrl1);
		SetDlgItemText(IDC_EDIT2, PicPath + _T("\\") + d + _T(".jpg"));
		SetDlgItemText(IDC_EDIT3, _T(" "));
		/*CRect Rect;
		(this->GetDlgItem(IDC_piCtrl2))->GetClientRect(&Rect);
		GetDC()->FillSolidRect(&Rect, RGB(240, 240, 240));*/
		GetDlgItem(IDC_piCtrl2)->ShowWindow(FALSE);
		MessageBox(_T("已讀取到第一張圖檔"), _T("提示"), MB_ICONINFORMATION);
		flag = flag + 2;
	}
	/*else if (flag - Pname_Num.size() >= 1)
	{
		MessageBox(_T("已讀取到最後一張圖檔"), _T("提示"), MB_ICONINFORMATION);
		flag = flag - 2;
	}*/
	else

	{
		d.Format(_T("%d"), flag);
		e.Format(_T("%d"), flag + 1);
		str = CT2A(PicPath + _T("\\") + d + _T(".jpg"));
		str2 = CT2A(PicPath + _T("\\") + e + _T(".jpg"));
		img = imread(str);//讀入圖檔
		img2 = imread(str2);
		ShowMatImage(img, IDC_piCtrl1);
		ShowMatImage(img2, IDC_piCtrl2);
		SetDlgItemText(IDC_EDIT2, PicPath + _T("\\") + d + _T(".jpg"));
		SetDlgItemText(IDC_EDIT3, PicPath + _T("\\") + e + _T(".jpg"));
	}
}           

跳轉到指定圖檔

BOOL IsConvertableToInt(CString & strName)
{
	BOOL flag = true;
	int count = 0;
	int length = strName.GetLength();
	if (length > 11)
	{
		flag = false;
	}
	else if (length == 0)
	{
		flag = false;
	}

	else
	{
		for (int j = 0; j < length; j++)
		{
			if (strName[j] > 57 || strName[j] < 48)
			{
				count++;
				if (count > 0)
				{
					flag = false;
					break;
				}
			}
		}
	}
	return flag;
}
void CAnnotationDlg::OnBnClickedJump()
{
	GetDlgItem(IDC_piCtrl2)->ShowWindow(TRUE);
	CString PicPath;
	GetDlgItemText(IDC_EDIT1, PicPath);
	CString JumpStr;
	GetDlgItemText(IDC_EDIT4, JumpStr);	
	if (IsConvertableToInt(JumpStr))
	{
		flag = _ttoi(JumpStr);
		if (flag > Pname_Num.size())
		{
			MessageBox(_T("超出查詢範圍"), _T("提示"), MB_ICONHAND);
		}
		else
		{			
			d.Format(_T("%d"), flag);
			e.Format(_T("%d"), flag + 1);
			str = CT2A(PicPath + _T("\\") + d + _T(".jpg"));
			str2 = CT2A(PicPath + _T("\\") + e + _T(".jpg"));
			img = imread(str);//讀入圖檔
			img2 = imread(str2);
			ShowMatImage(img, IDC_piCtrl1);
			ShowMatImage(img2, IDC_piCtrl2);
			SetDlgItemText(IDC_EDIT2, PicPath + _T("\\") + d + _T(".jpg"));
			SetDlgItemText(IDC_EDIT3, PicPath + _T("\\") + e + _T(".jpg"));
		}
		
	}
	else
	{
		MessageBox(_T("請輸入純數字"), _T("提示"), MB_ICONHAND);
	}
}           

用到的函數

ShowMatImage

void  CAnnotationDlg::ShowMatImage(Mat& src,int ID)

{
	try

	{
		if (src.empty())//沒有圖像時推出

		{
			return;
		}
		BITMAPINFO *pBmpInfo1 = NULL;

		if (src.channels() == 1)//灰階圖像顯示
		{
			pBmpInfo1 = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];bmp圖資訊頭	

			pBmpInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

			pBmpInfo1->bmiHeader.biWidth = src.cols;//src_rec.Width();

			pBmpInfo1->bmiHeader.biHeight = -src.rows; //-src_rec.Height();//為負值

			pBmpInfo1->bmiHeader.biPlanes = 1;

			pBmpInfo1->bmiHeader.biBitCount = 8;//八位

			pBmpInfo1->bmiHeader.biCompression = BI_RGB;

			pBmpInfo1->bmiHeader.biSizeImage = 0;

			pBmpInfo1->bmiHeader.biXPelsPerMeter = 0;

			pBmpInfo1->bmiHeader.biYPelsPerMeter = 0;

			pBmpInfo1->bmiHeader.biClrUsed = 0;

			pBmpInfo1->bmiHeader.biClrImportant = 0;

			for (int i = 0; i < 256; i++)//隻有灰階圖像需要顔色表

			{
				pBmpInfo1->bmiColors[i].rgbBlue = pBmpInfo1->bmiColors[i].rgbGreen = pBmpInfo1->bmiColors[i].rgbRed = (BYTE)i;

				pBmpInfo1->bmiColors[i].rgbReserved = 0;

			}
		}

		if (src.channels() == 3)

		{

			pBmpInfo1 = (BITMAPINFO*) new char[sizeof(BITMAPINFOHEADER)];

			pBmpInfo1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

			pBmpInfo1->bmiHeader.biWidth = src.cols;//src_rec.Width();

			pBmpInfo1->bmiHeader.biHeight = -src.rows; //-src_rec.Height();//為負值

			pBmpInfo1->bmiHeader.biPlanes = 1;

			pBmpInfo1->bmiHeader.biBitCount = 24;//24位

			pBmpInfo1->bmiHeader.biCompression = BI_RGB;

			pBmpInfo1->bmiHeader.biSizeImage = 0;

			pBmpInfo1->bmiHeader.biXPelsPerMeter = 0;

			pBmpInfo1->bmiHeader.biYPelsPerMeter = 0;

			pBmpInfo1->bmiHeader.biClrUsed = 0;

			pBmpInfo1->bmiHeader.biClrImportant = 0;

		}

		HDC h_dc = GetDlgItem(ID)->GetDC()->GetSafeHdc();

		CRect BoxSize;

		GetDlgItem(ID)->GetClientRect(&BoxSize);

		SetStretchBltMode(

			h_dc,           // handle to device context

			HALFTONE);



		int jj = StretchDIBits(h_dc, BoxSize.left, BoxSize.top, BoxSize.Width(), BoxSize.Height(), 0, 0, src.cols, src.rows, (void *)src.data,

			(BITMAPINFO*)pBmpInfo1, DIB_RGB_COLORS, SRCCOPY);

		delete[]pBmpInfo1;



		return;

	}

	catch (...)

	{

		return;

	}

}           

readImgNamefromFile

void  readImgNamefromFile(char* fileName, vector<CString>&imgNames)

{

	// vector清零 參數設定

	imgNames.clear();

	WIN32_FIND_DATA file;

	int i = 0;

	char tempFilePath[MAX_PATH + 1];

	char tempFileName[50];

	// 轉換輸入檔案名

	sprintf_s(tempFilePath, "%s/*", fileName);

	// 多位元組轉換

	WCHAR   wstr[MAX_PATH] = { 0 };

	MultiByteToWideChar(CP_ACP, 0, tempFilePath, -1, wstr, sizeof(wstr));

	// 查找該檔案待操作檔案的相關屬性讀取到WIN32_FIND_DATA

	HANDLE handle = FindFirstFile(wstr, &file);

	if (handle != INVALID_HANDLE_VALUE)

	{

		FindNextFile(handle, &file);

		FindNextFile(handle, &file);

		// 循環周遊得到檔案夾的所有檔案名	

		do

		{

			sprintf_s(tempFileName, "%s", fileName);

			imgNames.push_back((file.cFileName));

			//	imgNames[i].Insert(0, 1);

			i++;

		} while (FindNextFile(handle, &file));

	}

	FindClose(handle);

}