這個工程做得很簡潔 OpenCV+MFC的圖檔浏覽器
首先我的圖檔都是以數字命名的,是以查找起來有規律
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0DOyQGasdUZxgmMj5WNXpFdk1mYwVjMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLwMTM4IzN0EjM4ADOwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
定義全局變量
定義為全局變量是因為需要在多處通路這些變量
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);
}