├── .gitignore ├── LICENSE ├── OpenCVWindowExt.cpp ├── OpenCVWindowExt.h ├── OpenCV_ZoomInOut.cpp ├── OpenCV_ZoomInOut.vcxproj ├── OpenCV_ZoomInOut.vcxproj.filters ├── OpenCV_ZoomInOut.vcxproj.user ├── README.md ├── ZoomInOutPan.gif ├── apperance.jpg ├── test.bmp └── test2.bmp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Visual Studio 2019 cache/options directory 35 | .vs/ 36 | *.sdf 37 | bin/ 38 | obj/ 39 | Debug/ 40 | Release/ 41 | Debug_4X/ 42 | Release_4X/ 43 | *.opensdf 44 | *.tlog 45 | *.log 46 | *.idb 47 | *.pdb 48 | *.aps 49 | *.md 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2022, BoKuan Liu 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /OpenCVWindowExt.cpp: -------------------------------------------------------------------------------- 1 | #include "OpenCVWindowExt.h" 2 | 3 | void MouseCall (int event, int x, int y, int flag, void* pUserData) 4 | { 5 | COpenCVWindowExt* pParent = (COpenCVWindowExt*)pUserData; 6 | if (event == EVENT_MOUSEWHEEL) 7 | { 8 | if (getMouseWheelDelta (flag) > 0 && pParent->m_iScaleTimes != pParent->m_iMaxScaleTimes) 9 | pParent->m_iScaleTimes++; 10 | else if (getMouseWheelDelta (flag) < 0 && pParent->m_iScaleTimes != pParent->m_iMinScaleTimes) 11 | pParent->m_iScaleTimes--; 12 | 13 | if (pParent->m_iScaleTimes == 0) 14 | pParent->m_dCompensationX = pParent->m_dCompensationY = 0; 15 | 16 | //Pixel value = mouse offset (v.s. window's left top position) 17 | //But using x, y is not correct in Wheel Event. So, use pre recorded value 18 | x = pParent->ptLButtonDown.x; 19 | y = pParent->ptLButtonDown.y; 20 | double dPixelX = (pParent->m_iHorzScrollBarPos + x + pParent->m_dCompensationX) / pParent->m_dNewScale; 21 | double dPixelY = (pParent->m_iVertScrollBarPos + y + pParent->m_dCompensationY) / pParent->m_dNewScale; 22 | 23 | pParent->m_dNewScale = pParent->m_dInitialScale * pow (pParent->m_dScaleRatio, pParent->m_iScaleTimes); 24 | 25 | int iW = pParent->m_iOrgW; 26 | int iH = pParent->m_iOrgH; 27 | pParent->m_iHorzScrollBarRange_Max = int(pParent->m_dNewScale * iW - pParent->m_dInitialScale * iW); 28 | pParent->m_iVertScrollBarRange_Max = int(pParent->m_dNewScale * iH - pParent->m_dInitialScale * iH); 29 | int iBarPosX = int(dPixelX * pParent->m_dNewScale - x + 0.5); 30 | int iBarPosY = int(dPixelY * pParent->m_dNewScale - y + 0.5); 31 | pParent->SetHorzBarPos(iBarPosX); 32 | pParent->SetVertBarPos(iBarPosY); 33 | pParent->m_dCompensationX = -iBarPosX + (dPixelX * pParent->m_dNewScale - x); 34 | pParent->m_dCompensationY = -iBarPosY + (dPixelY * pParent->m_dNewScale - y); 35 | 36 | pParent->RefreshImage (); 37 | } 38 | else if (event == EVENT_RBUTTONDOWN) 39 | { 40 | pParent->ptRButtonDown.x = x; 41 | pParent->ptRButtonDown.y = y; 42 | } 43 | else if (flag == EVENT_FLAG_RBUTTON) 44 | { 45 | int iRButtonOffsetX = x - pParent->ptRButtonDown.x; 46 | int iRButtonOffsetY = y - pParent->ptRButtonDown.y; 47 | 48 | 49 | int iBarPosX = pParent->m_iHorzScrollBarPos_copy - iRButtonOffsetX; 50 | pParent->SetHorzBarPos (iBarPosX); 51 | 52 | 53 | int iBarPosY = pParent->m_iVertScrollBarPos_copy - iRButtonOffsetY; 54 | pParent->SetVertBarPos (iBarPosY); 55 | 56 | 57 | 58 | pParent->RefreshImage (); 59 | } 60 | else if (event == EVENT_MOUSEMOVE) 61 | { 62 | pParent->ptLButtonDown.x = x; 63 | pParent->ptLButtonDown.y = y; 64 | pParent->m_iHorzScrollBarPos_copy = pParent->m_iHorzScrollBarPos; 65 | pParent->m_iVertScrollBarPos_copy = pParent->m_iVertScrollBarPos; 66 | 67 | } 68 | } 69 | COpenCVWindowExt::COpenCVWindowExt (String strWindowName, int iFlag) 70 | { 71 | namedWindow (strWindowName, iFlag); 72 | setMouseCallback (strWindowName, MouseCall, this); 73 | m_strWindowName = strWindowName; 74 | 75 | //Initial values 76 | 77 | m_iScaleTimes = 0; 78 | m_iMaxScaleTimes = 5; 79 | m_iMinScaleTimes = 0; 80 | m_vecMatResize.resize (m_iMaxScaleTimes + 1); 81 | m_dCompensationX = 0; 82 | m_dCompensationY = 0; 83 | m_dInitialScale = 1; 84 | m_dNewScale = 1; 85 | m_dScaleRatio = 1.25; 86 | 87 | m_iOrgW = 0; 88 | m_iOrgH = 0; 89 | 90 | m_iHorzScrollBarPos = 0; 91 | m_iVertScrollBarPos = 0; 92 | 93 | m_iHorzScrollBarRange_Min = 0; 94 | m_iHorzScrollBarRange_Max = 1; 95 | m_iVertScrollBarRange_Min = 0; 96 | m_iVertScrollBarRange_Max = 1; 97 | } 98 | 99 | COpenCVWindowExt::~COpenCVWindowExt () 100 | { 101 | setMouseCallback (m_strWindowName, NULL); 102 | } 103 | 104 | bool COpenCVWindowExt::ImRead (String strFileName) 105 | { 106 | m_matSrc = imread (strFileName); 107 | if (m_matSrc.empty ()) 108 | return false; 109 | m_iOrgW = m_matSrc.cols; 110 | m_iOrgH = m_matSrc.rows; 111 | 112 | Size sizeInitial (m_matSrc.cols * m_dInitialScale, m_matSrc.rows * m_dInitialScale); 113 | resize (m_matSrc, m_vecMatResize[0], sizeInitial); 114 | 115 | if (!m_vecMatResize[0].empty ()) 116 | imshow (m_strWindowName, m_vecMatResize[0]); 117 | 118 | return !m_vecMatResize[0].empty (); 119 | } 120 | 121 | void COpenCVWindowExt::SetInitailScale (double dScale) 122 | { 123 | if (dScale <= 0) 124 | return; 125 | 126 | m_dInitialScale = dScale; 127 | m_dNewScale = dScale; 128 | } 129 | 130 | void COpenCVWindowExt::RefreshImage () 131 | { 132 | if (m_matSrc.empty ()) 133 | return; 134 | if (m_vecMatResize[m_iScaleTimes].empty ()) 135 | { 136 | Size size (int (m_dNewScale * m_matSrc.cols), int (m_dNewScale * m_matSrc.rows)); 137 | resize (m_matSrc, m_vecMatResize[m_iScaleTimes], size); 138 | } 139 | int iW = m_vecMatResize[0].cols - 1, iH = m_vecMatResize[0].rows - 1;//-1: for bar size 140 | 141 | 142 | Rect rectShow (Point (m_iHorzScrollBarPos, m_iVertScrollBarPos), Size (iW, iH)); 143 | imshow (m_strWindowName, m_vecMatResize[m_iScaleTimes] (rectShow)); 144 | } 145 | 146 | void COpenCVWindowExt::SetHorzBarPos (int iPos) 147 | { 148 | if (iPos > m_iHorzScrollBarRange_Max) 149 | m_iHorzScrollBarPos = m_iHorzScrollBarRange_Max; 150 | else if (iPos < 0) 151 | m_iHorzScrollBarPos = m_iHorzScrollBarRange_Min; 152 | else 153 | m_iHorzScrollBarPos = iPos; 154 | 155 | } 156 | 157 | void COpenCVWindowExt::SetVertBarPos (int iPos) 158 | { 159 | if (iPos > m_iVertScrollBarRange_Max) 160 | m_iVertScrollBarPos = m_iVertScrollBarRange_Max; 161 | else if (iPos < 0) 162 | m_iVertScrollBarPos = m_iVertScrollBarRange_Min; 163 | else 164 | m_iVertScrollBarPos = iPos; 165 | } 166 | -------------------------------------------------------------------------------- /OpenCVWindowExt.h: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using namespace cv; 4 | #pragma once 5 | class COpenCVWindowExt 6 | { 7 | public: 8 | COpenCVWindowExt (String strWindowName, int iFlag = 1); 9 | ~COpenCVWindowExt (); 10 | 11 | bool ImRead (String strFileName); 12 | void SetInitailScale (double dScale); 13 | 14 | 15 | void RefreshImage (); 16 | Mat m_matSrc; 17 | vector m_vecMatResize; 18 | String m_strWindowName; 19 | 20 | double m_dInitialScale; 21 | double m_dNewScale; 22 | double m_dScaleRatio; 23 | double m_dCompensationX; 24 | double m_dCompensationY; 25 | 26 | int m_iScaleTimes; 27 | int m_iMaxScaleTimes; 28 | int m_iMinScaleTimes; 29 | 30 | int m_iOrgW; 31 | int m_iOrgH; 32 | 33 | 34 | Point ptLButtonDown; 35 | Point ptRButtonDown; 36 | 37 | void SetHorzBarPos (int iPos); 38 | void SetVertBarPos (int iPos); 39 | int m_iHorzScrollBarPos; 40 | int m_iVertScrollBarPos; 41 | int m_iHorzScrollBarPos_copy; 42 | int m_iVertScrollBarPos_copy; 43 | 44 | 45 | int m_iHorzScrollBarRange_Min; 46 | int m_iHorzScrollBarRange_Max; 47 | int m_iVertScrollBarRange_Min; 48 | int m_iVertScrollBarRange_Max; 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /OpenCV_ZoomInOut.cpp: -------------------------------------------------------------------------------- 1 | // OpenCV_ZoomInOut.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include "OpenCVWindowExt.h" 6 | int main() 7 | { 8 | //std::cout << "Hello World!\n"; 9 | COpenCVWindowExt window ("Src"); 10 | window.SetInitailScale (0.8); 11 | window.ImRead ("test2.bmp"); 12 | waitKey (0); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /OpenCV_ZoomInOut.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {FB6E8B14-D473-4053-BB39-F4A224A194D8} 24 | Win32Proj 25 | OpenCVZoomInOut 26 | 10.0.19041.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | C:\OpenCV4.0\opencv\build\include;$(IncludePath) 76 | C:\OpenCV4.0\build2017\lib\Debug;$(LibraryPath) 77 | 78 | 79 | true 80 | 81 | 82 | false 83 | 84 | 85 | false 86 | 87 | 88 | 89 | 90 | 91 | Level3 92 | Disabled 93 | true 94 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 95 | true 96 | opencv_world401_vs2017.lib 97 | 98 | 99 | Console 100 | true 101 | opencv_world401d.lib;%(AdditionalDependencies) 102 | 103 | 104 | 105 | 106 | 107 | 108 | Level3 109 | Disabled 110 | true 111 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 112 | true 113 | 114 | 115 | Console 116 | true 117 | 118 | 119 | 120 | 121 | 122 | 123 | Level3 124 | MaxSpeed 125 | true 126 | true 127 | true 128 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 129 | true 130 | 131 | 132 | Console 133 | true 134 | true 135 | true 136 | 137 | 138 | 139 | 140 | 141 | 142 | Level3 143 | MaxSpeed 144 | true 145 | true 146 | true 147 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 148 | true 149 | 150 | 151 | Console 152 | true 153 | true 154 | true 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /OpenCV_ZoomInOut.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /OpenCV_ZoomInOut.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zoom-In-Out-with-OpenCV 2 | 3 | I believe a lot of people is concerned about this issue. So, I implemented a C++ class, containing OpneCV Window. 4 | This project can zoom in / out image showed on OpenCV window without other UI frameworks, like MFC, C#, Java Swing and etc. 5 | 6 | # Visual Effect: 7 | 8 | ![image](https://github.com/DennisLiu1993/Zoom-In-Out-with-OpenCV/blob/main/ZoomInOutPan.gif) 9 | 10 | # Usage: 11 | 12 | 1.Download Visual Studio and Install 13 | 14 | 2.Set up your OpenCV include directory, library directory, name of .lib 15 | 16 | 3.Place OpenCV.dll to the output directory of this project (for me, it's Zoom-In-Out-with-OpenCV\\Debug) 17 | 18 | 4.Run and Experience 19 | 20 | or you can just copy OpenCVWindowEx.h, OpenCVWindowEx.cpp to your own project 21 | 22 | # Class Usage: 23 | 24 | ``` 25 | COpenCVWindowExt window ("Src"); // Create an OpenCVWindowEx with name (same as original API) 26 | window.ImRead ("test2.bmp"); // Read an Image with this window and show it 27 | waitKey (0); // Wair for user's operation 28 | ``` 29 | -------------------------------------------------------------------------------- /ZoomInOutPan.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DennisLiu1993/Zoom-In-Out-with-OpenCV/9e61bb4a2e0675ede93e6fa22b17fe2f587be28b/ZoomInOutPan.gif -------------------------------------------------------------------------------- /apperance.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DennisLiu1993/Zoom-In-Out-with-OpenCV/9e61bb4a2e0675ede93e6fa22b17fe2f587be28b/apperance.jpg -------------------------------------------------------------------------------- /test.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DennisLiu1993/Zoom-In-Out-with-OpenCV/9e61bb4a2e0675ede93e6fa22b17fe2f587be28b/test.bmp -------------------------------------------------------------------------------- /test2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DennisLiu1993/Zoom-In-Out-with-OpenCV/9e61bb4a2e0675ede93e6fa22b17fe2f587be28b/test2.bmp --------------------------------------------------------------------------------