这个工程做得很简洁 OpenCV+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);
}