From 5003d04e5987a78c8cf56b96b8d1ffbdf4c2feef Mon Sep 17 00:00:00 2001 From: Noah Davis 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 &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(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; --