1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
From 5003d04e5987a78c8cf56b96b8d1ffbdf4c2feef Mon Sep 17 00:00:00 2001
From: Noah Davis <noahadvs@gmail.com>
Date: Sat, 4 Jul 2026 14:36:41 -0400
Subject: [PATCH] Remove OpenCV dependency
We don't have a reason to depend on OpenCV anymore
since KQuickImageEditor will no longer use it soon
and we don't really need to use a Lanczos filter.
This change should bring a measurable if not dramatic
improvement to startup time since a bicubic filter
(Qt::SmoothTransformation) has a simpler algorithm than
a Lanczos filter.
---
CMakeLists.txt | 1 -
src/CMakeLists.txt | 5 +-
src/Platforms/ImagePlatformKWin.cpp | 28 +++------
3 files changed, 10 insertions(+), 24 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0eea12dbf..fb0a8aa2f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -85,7 +85,6 @@ find_package(Wayland REQUIRED COMPONENTS Client)
find_package(PlasmaWaylandProtocols REQUIRED)
find_package(LayerShellQt REQUIRED)
find_package(KPipeWire)
-find_package(OpenCV 4.7 REQUIRED core imgproc)
find_package(PkgConfig REQUIRED)
set_package_properties(KPipeWire PROPERTIES DESCRIPTION
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 953e72677..524c94b6f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -93,11 +93,9 @@ ki18n_wrap_ui(spectacle
Gui/SettingsDialog/VideoSaveOptions.ui
)
-# Needed to compile with OpenCV
+# Needed to compile with Tesseract
target_compile_options (spectacle PRIVATE -fexceptions)
-target_include_directories(spectacle PUBLIC ${OpenCV_INCLUDE_DIRS})
-
target_link_libraries(spectacle PRIVATE
Qt::Concurrent
Qt::DBus
@@ -128,7 +126,6 @@ target_link_libraries(spectacle PRIVATE
Wayland::Client
LayerShellQt::Interface
KQuickImageEditor
- ${OpenCV_LIBRARIES}
PkgConfig::TESSERACT
)
diff --git a/src/Platforms/ImagePlatformKWin.cpp b/src/Platforms/ImagePlatformKWin.cpp
index 4521f0681..cd6a1e740 100644
--- a/src/Platforms/ImagePlatformKWin.cpp
+++ b/src/Platforms/ImagePlatformKWin.cpp
@@ -8,7 +8,6 @@
#include "Config.h"
#include "ExportManager.h"
#include "Geometry.h"
-#include "QtCV.h"
#include "DebugUtils.h"
#include "ImageMetaData.h"
@@ -104,30 +103,21 @@ QImage combinedImage(const QList<QImage> &images)
}
// We ceil to the next integer size up so that integer DPR images are always crisp.
const auto finalDpr = std::ceil(maxDpr);
- // An RGBA8888 based format is needed for compatibility with OpenCV.
- // If we used an ARGB32 based format, we'd need to swap red and blue.
- // Not sure what to do if we end up having different formats for different screens.
QImage finalImage{imageRect.size().toSize() * finalDpr, finalFormat};
finalImage.fill(Qt::transparent);
- auto mainMat = QtCV::qImageToMat(finalImage);
+ QPainter painter(&finalImage);
for (auto &image : images) {
- // Region Of Interest to put the image in the main image.
- // Prevent ROI from going out of bounds or having negative size.
- const auto rect = [finalDpr, &image, &finalImage] {
- auto pos = ImageMetaData::logicalXY(image) * finalDpr;
- auto size = image.deviceIndependentSize() * finalDpr;
- auto rect = Geometry::rectClipped(QRectF(pos, size).toRect(), //
- finalImage.rect());
- return cv::Rect(rect.x(), rect.y(), rect.width(), rect.height());
- }();
+ const auto pos = ImageMetaData::logicalXY(image) * finalDpr;
+ const auto size = (image.deviceIndependentSize() * finalDpr).toSize();
const auto imageDpr = image.devicePixelRatio();
const bool hasIntDpr = static_cast<int>(imageDpr) == imageDpr;
- const auto interpolation = hasIntDpr ? cv::INTER_AREA : cv::INTER_LANCZOS4;
- auto rgbaImage = image.format() == finalImage.format() ? image : image.convertedTo(finalFormat);
- const auto mat = QtCV::qImageToMat(rgbaImage);
- // Will just copy if there's no difference in size
- cv::resize(mat, mainMat(rect), rect.size(), 0, 0, interpolation);
+ const auto interpolation = hasIntDpr ? Qt::FastTransformation : Qt::SmoothTransformation;
+ painter.drawImage(QRectF{pos, size},
+ size == image.size() //
+ ? image
+ : image.scaled(size, Qt::KeepAspectRatio, interpolation));
}
+ painter.end();
finalImage.setDevicePixelRatio(finalDpr);
ImageMetaData::setSubGeometryList(finalImage, geometryList);
return finalImage;
--
|