├── MyImageViewer
├── MyImageViewer.rc
├── lena.bmp
├── MyImageViewer.qrc
├── MyImageViewer.ico
├── main.cpp
├── MyImageViewer.cpp
├── MyImageViewer.h
├── MyImageViewer.ui
├── GeneratedFiles
│ ├── qrc_MyImageViewer.cpp
│ └── ui_MyImageViewer.h
├── QImageViewer.h
├── MyImageViewer.vcxproj.filters
├── MyImageViewer.vcxproj
└── QImageViewer.cpp
├── MyImageViewer.sln
├── .gitattributes
└── .gitignore
/MyImageViewer/MyImageViewer.rc:
--------------------------------------------------------------------------------
1 | IDI_ICON1 ICON DISCARDABLE "MyImageViewer.ico"
2 |
3 |
--------------------------------------------------------------------------------
/MyImageViewer/lena.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuchang0523/MyImageViewer/HEAD/MyImageViewer/lena.bmp
--------------------------------------------------------------------------------
/MyImageViewer/MyImageViewer.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/MyImageViewer/MyImageViewer.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuchang0523/MyImageViewer/HEAD/MyImageViewer/MyImageViewer.ico
--------------------------------------------------------------------------------
/MyImageViewer/main.cpp:
--------------------------------------------------------------------------------
1 | #include "MyImageViewer.h"
2 | #include
3 |
4 | int main(int argc, char *argv[])
5 | {
6 | QApplication a(argc, argv);
7 | MyImageViewer w;
8 | w.show();
9 | return a.exec();
10 | }
11 |
--------------------------------------------------------------------------------
/MyImageViewer/MyImageViewer.cpp:
--------------------------------------------------------------------------------
1 | #include "MyImageViewer.h"
2 |
3 | MyImageViewer::MyImageViewer(QWidget *parent)
4 | : QWidget(parent)
5 | {
6 | ui.setupUi(this);
7 | ui.widget->setImage(QImage("lena.bmp"));
8 | }
9 |
10 | void MyImageViewer::on_widget_Coordinate(QString str)
11 | {
12 | ui.label->setText(str);
13 | }
14 |
--------------------------------------------------------------------------------
/MyImageViewer/MyImageViewer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include "ui_MyImageViewer.h"
5 |
6 | class MyImageViewer : public QWidget
7 | {
8 | Q_OBJECT
9 |
10 | public:
11 | MyImageViewer(QWidget *parent = Q_NULLPTR);
12 |
13 | private slots:
14 | void on_widget_Coordinate(QString str);
15 |
16 | private:
17 | Ui::MyImageViewerClass ui;
18 | };
19 |
--------------------------------------------------------------------------------
/MyImageViewer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.168
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyImageViewer", "MyImageViewer\MyImageViewer.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Release|x64 = Release|x64
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64
15 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64
16 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64
17 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {0CA2FCAC-331E-48D0-8C54-A2077C2509F1}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/MyImageViewer/MyImageViewer.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MyImageViewerClass
4 |
5 |
6 |
7 | 0
8 | 0
9 | 929
10 | 668
11 |
12 |
13 |
14 | MyImageViewer
15 |
16 |
17 | -
18 |
19 |
20 | -
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | QImageViewer
33 | QWidget
34 |
35 | 1
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/MyImageViewer/GeneratedFiles/qrc_MyImageViewer.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | ** Resource object code
3 | **
4 | ** Created by: The Resource Compiler for Qt version 5.11.1
5 | **
6 | ** WARNING! All changes made in this file will be lost!
7 | *****************************************************************************/
8 |
9 | #ifdef QT_NAMESPACE
10 | # define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
11 | # define QT_RCC_MANGLE_NAMESPACE0(x) x
12 | # define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
13 | # define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
14 | # define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
15 | QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
16 | #else
17 | # define QT_RCC_PREPEND_NAMESPACE(name) name
18 | # define QT_RCC_MANGLE_NAMESPACE(name) name
19 | #endif
20 |
21 | #ifdef QT_NAMESPACE
22 | namespace QT_NAMESPACE {
23 | #endif
24 |
25 | #ifdef QT_NAMESPACE
26 | }
27 | #endif
28 |
29 | int QT_RCC_MANGLE_NAMESPACE(qInitResources_MyImageViewer)();
30 | int QT_RCC_MANGLE_NAMESPACE(qInitResources_MyImageViewer)()
31 | {
32 | return 1;
33 | }
34 |
35 | int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_MyImageViewer)();
36 | int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_MyImageViewer)()
37 | {
38 | return 1;
39 | }
40 |
41 | namespace {
42 | struct initializer {
43 | initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources_MyImageViewer)(); }
44 | ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources_MyImageViewer)(); }
45 | } dummy;
46 | }
47 |
--------------------------------------------------------------------------------
/MyImageViewer/QImageViewer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | class QImageViewer :
6 | public QWidget
7 | {
8 | Q_OBJECT
9 | public:
10 | QImageViewer(QWidget*parent = Q_NULLPTR);
11 | virtual ~QImageViewer(void);
12 |
13 | void setImage(QImage &image);
14 | QImage getImage() { return m_sourceImage; }
15 | QRect getSelection() { return m_selection; }
16 | QImage getSelectionImage();
17 | void zoom();
18 | QPointF screenToWorld(QPointF &pt, bool includeRotation = true);
19 | QPointF worldToScreen(QPointF &pt, bool includeRotation = true);
20 |
21 | void SetRefinedRect(int x, int y, int width, int height);
22 |
23 | inline QVector getPixelBoundary(QRect &rect);
24 |
25 | protected:
26 | virtual void paintEvent(QPaintEvent * event);
27 | virtual void mouseMoveEvent(QMouseEvent * event);
28 | virtual void mousePressEvent(QMouseEvent * event);
29 | virtual void mouseReleaseEvent(QMouseEvent * event);
30 | virtual void keyPressEvent(QKeyEvent * event);
31 | virtual void wheelEvent(QWheelEvent *event);
32 | virtual void mouseDoubleClickEvent(QMouseEvent * event);
33 |
34 | QTransform getTransform(bool includeRotation = true);
35 |
36 | signals:
37 | void SelectedRect(QRect);
38 | void Coordinate(QString);
39 |
40 |
41 | private:
42 | QImage m_sourceImage;
43 |
44 | qreal m_scale;
45 | qreal m_rotation;
46 | QPointF m_scaleBasePt;
47 |
48 | QPointF m_lastPressedMousePt;
49 | QRect m_selection;
50 |
51 | QRect m_refined;
52 |
53 | bool m_buttonLeftPressed;
54 | bool m_buttonMiddlePressed;
55 | };
56 |
--------------------------------------------------------------------------------
/MyImageViewer/GeneratedFiles/ui_MyImageViewer.h:
--------------------------------------------------------------------------------
1 | /********************************************************************************
2 | ** Form generated from reading UI file 'MyImageViewer.ui'
3 | **
4 | ** Created by: Qt User Interface Compiler version 5.11.1
5 | **
6 | ** WARNING! All changes made in this file will be lost when recompiling UI file!
7 | ********************************************************************************/
8 |
9 | #ifndef UI_MYIMAGEVIEWER_H
10 | #define UI_MYIMAGEVIEWER_H
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include "qimageviewer.h"
18 |
19 | QT_BEGIN_NAMESPACE
20 |
21 | class Ui_MyImageViewerClass
22 | {
23 | public:
24 | QGridLayout *gridLayout;
25 | QImageViewer *widget;
26 | QLabel *label;
27 |
28 | void setupUi(QWidget *MyImageViewerClass)
29 | {
30 | if (MyImageViewerClass->objectName().isEmpty())
31 | MyImageViewerClass->setObjectName(QStringLiteral("MyImageViewerClass"));
32 | MyImageViewerClass->resize(929, 668);
33 | gridLayout = new QGridLayout(MyImageViewerClass);
34 | gridLayout->setSpacing(6);
35 | gridLayout->setContentsMargins(11, 11, 11, 11);
36 | gridLayout->setObjectName(QStringLiteral("gridLayout"));
37 | widget = new QImageViewer(MyImageViewerClass);
38 | widget->setObjectName(QStringLiteral("widget"));
39 |
40 | gridLayout->addWidget(widget, 1, 0, 1, 1);
41 |
42 | label = new QLabel(MyImageViewerClass);
43 | label->setObjectName(QStringLiteral("label"));
44 |
45 | gridLayout->addWidget(label, 0, 0, 1, 1);
46 |
47 | gridLayout->setRowStretch(1, 1);
48 |
49 | retranslateUi(MyImageViewerClass);
50 |
51 | QMetaObject::connectSlotsByName(MyImageViewerClass);
52 | } // setupUi
53 |
54 | void retranslateUi(QWidget *MyImageViewerClass)
55 | {
56 | MyImageViewerClass->setWindowTitle(QApplication::translate("MyImageViewerClass", "MyImageViewer", nullptr));
57 | label->setText(QString());
58 | } // retranslateUi
59 |
60 | };
61 |
62 | namespace Ui {
63 | class MyImageViewerClass: public Ui_MyImageViewerClass {};
64 | } // namespace Ui
65 |
66 | QT_END_NAMESPACE
67 |
68 | #endif // UI_MYIMAGEVIEWER_H
69 |
--------------------------------------------------------------------------------
/MyImageViewer/MyImageViewer.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;xsd
11 |
12 |
13 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}
14 | qrc;*
15 | false
16 |
17 |
18 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3}
19 | ui
20 |
21 |
22 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}
23 | qrc;*
24 | false
25 |
26 |
27 | {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}
28 | moc;h;cpp
29 | False
30 |
31 |
32 |
33 |
34 | Source Files
35 |
36 |
37 | Source Files
38 |
39 |
40 | Source Files
41 |
42 |
43 |
44 |
45 | Header Files
46 |
47 |
48 | Header Files
49 |
50 |
51 |
52 |
53 | Form Files
54 |
55 |
56 |
57 |
58 | Resource Files
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/MyImageViewer/MyImageViewer.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 | {B12702AD-ABFB-343A-A199-8E24837244A3}
15 | Qt4VSv1.0
16 | 10.0.17763.0
17 |
18 |
19 |
20 | Application
21 | v141
22 |
23 |
24 | Application
25 | v141
26 |
27 |
28 |
29 | $(MSBuildProjectDirectory)\QtMsBuild
30 |
31 |
32 | $(SolutionDir)$(Platform)\$(Configuration)\
33 |
34 |
35 | $(SolutionDir)$(Platform)\$(Configuration)\
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | true
55 | UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)
56 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)
57 | Disabled
58 | ProgramDatabase
59 | MultiThreadedDebugDLL
60 | true
61 |
62 |
63 | Console
64 | $(OutDir)\$(ProjectName).exe
65 | $(QTDIR)\lib;%(AdditionalLibraryDirectories)
66 | true
67 | qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;%(AdditionalDependencies)
68 |
69 |
70 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
71 | Moc'ing %(Identity)...
72 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)
73 | UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)
74 |
75 |
76 | Uic'ing %(Identity)...
77 | .\GeneratedFiles\ui_%(Filename).h
78 |
79 |
80 | Rcc'ing %(Identity)...
81 | .\GeneratedFiles\qrc_%(Filename).cpp
82 |
83 |
84 |
85 |
86 | true
87 | UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)
88 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)
89 |
90 | MultiThreadedDLL
91 | true
92 |
93 |
94 | Windows
95 | $(OutDir)\$(ProjectName).exe
96 | $(QTDIR)\lib;%(AdditionalLibraryDirectories)
97 | false
98 | qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;%(AdditionalDependencies)
99 |
100 |
101 | .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
102 | Moc'ing %(Identity)...
103 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)
104 | UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)
105 |
106 |
107 | Uic'ing %(Identity)...
108 | .\GeneratedFiles\ui_%(Filename).h
109 |
110 |
111 | Rcc'ing %(Identity)...
112 | .\GeneratedFiles\qrc_%(Filename).cpp
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName)\.;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets
135 | UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB
136 | .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName)\.;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets
137 | UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/MyImageViewer/QImageViewer.cpp:
--------------------------------------------------------------------------------
1 | #include "QImageViewer.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | QImageViewer::QImageViewer(QWidget*parent /*= 0*/)
8 | :QWidget(parent)
9 | {
10 | m_scale = 1.0;
11 | m_rotation = 0.0;
12 | m_scaleBasePt = QPointF(0, 0);
13 | m_buttonLeftPressed = false;
14 | m_buttonMiddlePressed = false;
15 | setMouseTracking(true);
16 | }
17 |
18 | QImageViewer::~QImageViewer(void)
19 | {
20 | }
21 |
22 | void QImageViewer::setImage(QImage &image)
23 | {
24 | m_sourceImage = image;
25 | //zoom();
26 | }
27 |
28 | QImage QImageViewer::getSelectionImage()
29 | {
30 | if (m_sourceImage.isNull())
31 | {
32 | return QImage();
33 | }
34 |
35 | QImage img;
36 | if (m_rotation != 0)
37 | {
38 | QTransform t;
39 | t.rotate(m_rotation);
40 | img = m_sourceImage.transformed(t);
41 |
42 | QPointF c1(m_sourceImage.width() / qreal(2), m_sourceImage.height() / qreal(2));
43 | QPointF c2(img.width() / qreal(2), img.height() / qreal(2));
44 |
45 | QRect r = m_selection.translated((c2 - c1).toPoint());
46 | img = img.copy(r);
47 | }
48 | else
49 | {
50 | img = m_sourceImage.copy(m_selection);
51 | }
52 |
53 | return img;
54 | }
55 |
56 | void QImageViewer::zoom()
57 | {
58 | if (!m_sourceImage.isNull())
59 | {
60 | double sx = m_sourceImage.width() * 1.01 / this->width();
61 | double sy = m_sourceImage.height() * 1.01 / this->height();
62 | m_scale = 1. / qMax(sx, sy);
63 | qDebug() << QStringLiteral("放大倍数:%1").arg(m_scale);
64 | qreal x = this->width() - m_sourceImage.width() * m_scale;
65 | qreal y = this->height() - m_sourceImage.height() * m_scale;
66 | m_scaleBasePt = QPointF(x / 2, y / 2);
67 | repaint();
68 | }
69 | }
70 |
71 | QPointF QImageViewer::screenToWorld(QPointF &pt, bool includeRotation/* = true*/)
72 | {
73 | QTransform t = getTransform(includeRotation);
74 | QTransform t1 = t.inverted();
75 | return t1.map(pt);
76 | }
77 |
78 | QPointF QImageViewer::worldToScreen(QPointF &pt, bool includeRotation/* = true*/)
79 | {
80 | QTransform t = getTransform(includeRotation);
81 | return t.map(pt);
82 | }
83 |
84 |
85 | void QImageViewer::SetRefinedRect(int x, int y, int width, int height)
86 | {
87 | m_refined = QRect(x, y, width, height);
88 | repaint();
89 | }
90 |
91 |
92 | QVector QImageViewer::getPixelBoundary(QRect &rect)
93 | {
94 | QVector lines;
95 | QPointF left, right, top, buttom;
96 | for (int y = rect.y(); y < rect.y() + rect.height(); ++y)
97 | {
98 | left = worldToScreen(QPointF(rect.x() - 1, y));
99 | right = worldToScreen(QPointF(rect.x() + rect.width() + 1, y));
100 | lines.append(QLineF(left, right));
101 | }
102 | for (int x = rect.x(); x < rect.x() + rect.width(); ++x)
103 | {
104 | top = worldToScreen(QPointF(x, rect.y() - 1));
105 | buttom = worldToScreen(QPointF(x, rect.y() + rect.height() + 1));
106 | lines.append(QLineF(top, buttom));
107 | }
108 | return lines;
109 | }
110 |
111 | void QImageViewer::paintEvent(QPaintEvent * event)
112 | {
113 | QPainter p(this);
114 | p.fillRect(this->rect(), Qt::gray);
115 |
116 | p.save();
117 | QTransform transform = getTransform();
118 | p.setWorldTransform(transform);
119 | p.drawImage(QPoint(0, 0), m_sourceImage);
120 | p.restore();
121 |
122 | if (!m_selection.isNull())
123 | {
124 | p.save();
125 | QTransform transform = getTransform(false);
126 | p.setWorldTransform(transform);
127 | QVector lines;
128 | qreal x1 = m_selection.left();
129 | qreal y1 = m_selection.top();
130 | qreal x2 = m_selection.right();
131 | qreal y2 = m_selection.bottom();
132 |
133 | lines.append(QLineF(x1, y1, x2, y1));
134 | lines.append(QLineF(x2, y1, x2, y2));
135 | lines.append(QLineF(x2, y2, x1, y2));
136 | lines.append(QLineF(x1, y2, x1, y1));
137 |
138 | QPen pen(Qt::red);
139 | pen.setStyle(Qt::PenStyle::DashDotLine);
140 | QTransform t1 = transform.inverted();
141 | QPointF pt = t1.map(QPointF(0, 0));
142 | QPointF pt1 = t1.map(QPointF(1, 0));
143 | pen.setWidthF(abs(pt1.x() - pt.x()));
144 | p.setPen(pen);
145 | p.drawLines(lines);
146 | p.restore();
147 | }
148 |
149 | if (!m_refined.isNull())
150 | {
151 | p.save();
152 | QTransform transform = getTransform(false);
153 | p.setWorldTransform(transform);
154 | QVector lines;
155 | qreal x1 = m_refined.left();
156 | qreal y1 = m_refined.top();
157 | qreal x2 = m_refined.right();
158 | qreal y2 = m_refined.bottom();
159 |
160 | lines.append(QLineF(x1, y1, x2, y1));
161 | lines.append(QLineF(x2, y1, x2, y2));
162 | lines.append(QLineF(x2, y2, x1, y2));
163 | lines.append(QLineF(x1, y2, x1, y1));
164 |
165 | QPen pen(Qt::green);
166 | //pen.setStyle(Qt::PenStyle::DashDotLine);
167 | QTransform t1 = transform.inverted();
168 | QPointF pt = t1.map(QPointF(0, 0));
169 | QPointF pt1 = t1.map(QPointF(1, 0));
170 | pen.setWidthF(abs(pt1.x() - pt.x()));
171 | p.setPen(pen);
172 | p.drawLines(lines);
173 | p.restore();
174 | }
175 |
176 | if (m_scale > 30)
177 | {
178 | //1.获得视场内点坐标
179 | QPointF tl = screenToWorld(QPointF(this->x(), this->y()));
180 | QPointF br = screenToWorld(QPointF(this->size().width(), this->size().height()));
181 | QRect rectInView(tl.toPoint(), br.toPoint());
182 |
183 | QPen pen(Qt::gray);
184 | p.setPen(pen);
185 | QVector lines = getPixelBoundary(rectInView);
186 | p.drawLines(lines);
187 | //p.restore();
188 | }
189 |
190 | if (m_scale > 48)
191 | {
192 | //qDebug() << "paint value!";
193 | //1.获得视场内点坐标
194 | QPointF tl = screenToWorld(QPointF(this->x(), this->y()));
195 | QPointF br = screenToWorld(QPointF(this->size().width(), this->size().height()));
196 |
197 | //TODO:获取每个点的像素值
198 | QRect rectInView(tl.toPoint(), br.toPoint());
199 | QVector pointsOnScreen;
200 | QVector valueString;
201 |
202 | for (int y = rectInView.y(); y < rectInView.y() + rectInView.height(); ++y)
203 | {
204 | for (int x = rectInView.x(); x < rectInView.x() + rectInView.width(); ++x)
205 | {
206 | QRgb pixValue = m_sourceImage.pixel(x, y);
207 | QPointF pointOnScreen = worldToScreen(QPointF(x + 0.5, y + 0.5));
208 | pointsOnScreen.push_back(pointOnScreen);
209 | valueString.push_back(QString::number(qGray(pixValue)));
210 | }
211 |
212 | }
213 |
214 | //画出像素值
215 | QPen pen(Qt::gray);
216 | p.setPen(pen);
217 | QFont font;
218 | font.setFamily("Times");
219 | font.setPointSize(8);
220 | p.setFont(font);
221 | for (int i = 0; i < pointsOnScreen.size(); ++i)
222 | {
223 | int strWidth = p.fontMetrics().width(valueString[i]);
224 | int strHeight = p.fontMetrics().height();
225 | QPointF fontPoint =
226 | QPointF(pointsOnScreen[i]
227 | - QPointF(strWidth / 2.0, -strHeight / 4.0));
228 | QRect fontRect(fontPoint.x() - 1,
229 | fontPoint.y() - strHeight + strHeight / 8,
230 | strWidth + 2, strHeight + +strHeight / 8);
231 | p.setPen(Qt::gray);
232 | p.setBrush(QBrush(Qt::gray));
233 | p.drawRect(fontRect);
234 | p.setPen(Qt::black);
235 | p.drawText(fontPoint, valueString[i]);
236 | }
237 | }
238 | }
239 |
240 | void QImageViewer::mouseMoveEvent(QMouseEvent * event)
241 | {
242 | if (m_buttonLeftPressed)
243 | {
244 | QPointF curPt = event->pos();
245 | QPointF pt1 = screenToWorld(m_lastPressedMousePt, false);
246 | QPointF pt2 = screenToWorld(curPt, false);
247 |
248 | m_selection = QRect(QPoint(qMin(pt1.x(), pt2.x()), qMin(pt1.y(), pt2.y())), QPoint(qMax(pt1.x(), pt2.x()), qMax(pt1.y(), pt2.y())));
249 | repaint();
250 | }
251 | else if (m_buttonMiddlePressed)
252 | {
253 | QPointF mv = event->pos() - m_lastPressedMousePt;
254 | m_scaleBasePt += mv;
255 | m_lastPressedMousePt = event->pos();
256 | repaint();
257 | }
258 | if (!m_sourceImage.isNull())
259 | {
260 | QPointF curPt = event->pos();
261 | QPointF pt2 = screenToWorld(curPt, false);
262 | //qDebug() << pt2.toPoint();
263 | int x = pt2.x();
264 | int y = pt2.y();
265 | QRgb pixValue = m_sourceImage.pixel(x, y);
266 | QString str = "[" + QString::number(x) + "," +
267 | QString::number(y) + "]---" +
268 | QString::number(qGray(pixValue));
269 | emit Coordinate(str);
270 | }
271 | }
272 |
273 | void QImageViewer::mousePressEvent(QMouseEvent * event)
274 | {
275 | if (event->button() == Qt::LeftButton)
276 | m_buttonMiddlePressed = true;
277 | //m_buttonLeftPressed = true;
278 | else if (event->button() == Qt::MidButton)
279 | m_buttonMiddlePressed = true;
280 | else if (event->button() == Qt::RightButton)
281 | {
282 | }
283 | m_lastPressedMousePt = event->pos();
284 | }
285 |
286 | void QImageViewer::mouseReleaseEvent(QMouseEvent * event)
287 | {
288 | m_buttonLeftPressed = false;
289 | m_buttonMiddlePressed = false;
290 | if (event->button() == Qt::LeftButton)
291 | {
292 | emit SelectedRect(m_selection);
293 | //qDebug() << m_selection;
294 | }
295 | if (event->button() == Qt::RightButton)
296 | {
297 | m_selection = QRect();
298 | m_refined = QRect();
299 | emit SelectedRect(m_selection);
300 | repaint();
301 | }
302 | }
303 |
304 | void QImageViewer::keyPressEvent(QKeyEvent * event)
305 | {
306 |
307 | }
308 |
309 | void QImageViewer::wheelEvent(QWheelEvent *event)
310 | {
311 | if (!m_sourceImage.isNull())
312 | {
313 | QPoint angle = event->angleDelta();
314 |
315 | if (event->modifiers() == Qt::ShiftModifier)
316 | {
317 | m_rotation += angle.y() / 8;
318 | }
319 | else
320 | {
321 | QPointF pt1 = event->posF();
322 | QPointF p = worldToScreen(QPointF(0, 0));
323 |
324 | QPointF pt2;
325 | if (angle.y() > 0)
326 | {
327 | pt2 = pt1 + (p - pt1)*0.618;
328 | m_scale *= 0.618;
329 | }
330 | else
331 | {
332 | pt2 = pt1 + (p - pt1) / 0.618;
333 | m_scale /= 0.618;
334 | }
335 |
336 | QTransform rotationTransform;
337 | QPointF c(m_sourceImage.width() / qreal(2), m_sourceImage.height() / qreal(2));
338 | rotationTransform.translate(c.x(), c.y());
339 | rotationTransform.rotate(m_rotation);
340 | rotationTransform.translate(-c.x(), -c.y());
341 |
342 | QTransform scalingTransform;
343 | scalingTransform.scale(m_scale, m_scale);
344 |
345 | QPointF a3 = (scalingTransform.map(rotationTransform.map(QPointF(0, 0)))); //ok
346 |
347 | QPointF pt3 = pt2 - a3;
348 | m_scaleBasePt = pt3;
349 | }
350 |
351 | qDebug() << QStringLiteral("放大倍数:%1").arg(m_scale);
352 | repaint();
353 | }
354 | }
355 |
356 | void QImageViewer::mouseDoubleClickEvent(QMouseEvent * event)
357 | {
358 | if (event->button() == Qt::LeftButton)
359 | {
360 | zoom();
361 | }
362 | }
363 |
364 | QTransform QImageViewer::getTransform(bool includeRotation/* = true*/)
365 | {
366 | QTransform transform;
367 | if (!m_sourceImage.isNull())
368 | {
369 | transform.translate(m_scaleBasePt.x(), m_scaleBasePt.y());
370 |
371 | transform.scale(m_scale, m_scale);
372 | if (includeRotation)
373 | {
374 | QPointF c(m_sourceImage.width() / qreal(2), m_sourceImage.height() / qreal(2));
375 | transform.translate(c.x(), c.y());
376 | transform.rotate(m_rotation);
377 | transform.translate(-c.x(), -c.y());
378 | }
379 |
380 | }
381 | return transform;
382 | }
383 |
--------------------------------------------------------------------------------