mirror of
https://git.outfoxxed.me/quickshell/quickshell.git
synced 2026-04-10 06:11:54 +10:00
core/colorquant: add imageRect option for cropping image
This commit is contained in:
parent
4b751ccb0d
commit
50cdf98868
4 changed files with 54 additions and 7 deletions
|
|
@ -1,7 +1,10 @@
|
||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
project(quickshell VERSION "0.2.1" LANGUAGES CXX C)
|
project(quickshell VERSION "0.2.1" LANGUAGES CXX C)
|
||||||
|
|
||||||
set(UNRELEASED_FEATURES "network.2")
|
set(UNRELEASED_FEATURES
|
||||||
|
"network.2"
|
||||||
|
"colorquant-imagerect"
|
||||||
|
)
|
||||||
|
|
||||||
set(QT_MIN_VERSION "6.6.0")
|
set(QT_MIN_VERSION "6.6.0")
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ set shell id.
|
||||||
- Added generic WindowManager interface implementing ext-workspace.
|
- Added generic WindowManager interface implementing ext-workspace.
|
||||||
- Added ext-background-effect window blur support.
|
- Added ext-background-effect window blur support.
|
||||||
- Added per-corner radius support to Region.
|
- Added per-corner radius support to Region.
|
||||||
|
- Added ColorQuantizer region selection.
|
||||||
|
|
||||||
## Other Changes
|
## Other Changes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <qnumeric.h>
|
#include <qnumeric.h>
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qqmllist.h>
|
#include <qqmllist.h>
|
||||||
|
#include <qrect.h>
|
||||||
#include <qrgb.h>
|
#include <qrgb.h>
|
||||||
#include <qthreadpool.h>
|
#include <qthreadpool.h>
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
|
|
@ -24,9 +25,15 @@ namespace {
|
||||||
QS_LOGGING_CATEGORY(logColorQuantizer, "quickshell.colorquantizer", QtWarningMsg);
|
QS_LOGGING_CATEGORY(logColorQuantizer, "quickshell.colorquantizer", QtWarningMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorQuantizerOperation::ColorQuantizerOperation(QUrl* source, qreal depth, qreal rescaleSize)
|
ColorQuantizerOperation::ColorQuantizerOperation(
|
||||||
|
QUrl* source,
|
||||||
|
qreal depth,
|
||||||
|
QRect imageRect,
|
||||||
|
qreal rescaleSize
|
||||||
|
)
|
||||||
: source(source)
|
: source(source)
|
||||||
, maxDepth(depth)
|
, maxDepth(depth)
|
||||||
|
, imageRect(imageRect)
|
||||||
, rescaleSize(rescaleSize) {
|
, rescaleSize(rescaleSize) {
|
||||||
this->setAutoDelete(false);
|
this->setAutoDelete(false);
|
||||||
}
|
}
|
||||||
|
|
@ -37,6 +44,11 @@ void ColorQuantizerOperation::quantizeImage(const QAtomicInteger<bool>& shouldCa
|
||||||
this->colors.clear();
|
this->colors.clear();
|
||||||
|
|
||||||
auto image = QImage(this->source->toLocalFile());
|
auto image = QImage(this->source->toLocalFile());
|
||||||
|
|
||||||
|
if (this->imageRect.isValid()) {
|
||||||
|
image = image.copy(this->imageRect);
|
||||||
|
}
|
||||||
|
|
||||||
if ((image.width() > this->rescaleSize || image.height() > this->rescaleSize)
|
if ((image.width() > this->rescaleSize || image.height() > this->rescaleSize)
|
||||||
&& this->rescaleSize > 0)
|
&& this->rescaleSize > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -198,16 +210,27 @@ void ColorQuantizer::setDepth(qreal depth) {
|
||||||
this->mDepth = depth;
|
this->mDepth = depth;
|
||||||
emit this->depthChanged();
|
emit this->depthChanged();
|
||||||
|
|
||||||
if (this->componentCompleted) this->quantizeAsync();
|
if (this->componentCompleted && !this->mSource.isEmpty()) this->quantizeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ColorQuantizer::setImageRect(QRect imageRect) {
|
||||||
|
if (this->mImageRect != imageRect) {
|
||||||
|
this->mImageRect = imageRect;
|
||||||
|
emit this->imageRectChanged();
|
||||||
|
|
||||||
|
if (this->componentCompleted && !this->mSource.isEmpty()) this->quantizeAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorQuantizer::resetImageRect() { this->setImageRect(QRect()); }
|
||||||
|
|
||||||
void ColorQuantizer::setRescaleSize(int rescaleSize) {
|
void ColorQuantizer::setRescaleSize(int rescaleSize) {
|
||||||
if (this->mRescaleSize != rescaleSize) {
|
if (this->mRescaleSize != rescaleSize) {
|
||||||
this->mRescaleSize = rescaleSize;
|
this->mRescaleSize = rescaleSize;
|
||||||
emit this->rescaleSizeChanged();
|
emit this->rescaleSizeChanged();
|
||||||
|
|
||||||
if (this->componentCompleted) this->quantizeAsync();
|
if (this->componentCompleted && !this->mSource.isEmpty()) this->quantizeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,8 +244,13 @@ void ColorQuantizer::quantizeAsync() {
|
||||||
if (this->liveOperation) this->cancelAsync();
|
if (this->liveOperation) this->cancelAsync();
|
||||||
|
|
||||||
qCDebug(logColorQuantizer) << "Starting color quantization asynchronously";
|
qCDebug(logColorQuantizer) << "Starting color quantization asynchronously";
|
||||||
this->liveOperation =
|
|
||||||
new ColorQuantizerOperation(&this->mSource, this->mDepth, this->mRescaleSize);
|
this->liveOperation = new ColorQuantizerOperation(
|
||||||
|
&this->mSource,
|
||||||
|
this->mDepth,
|
||||||
|
this->mImageRect,
|
||||||
|
this->mRescaleSize
|
||||||
|
);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
this->liveOperation,
|
this->liveOperation,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <qproperty.h>
|
#include <qproperty.h>
|
||||||
#include <qqmlintegration.h>
|
#include <qqmlintegration.h>
|
||||||
#include <qqmlparserstatus.h>
|
#include <qqmlparserstatus.h>
|
||||||
|
#include <qrect.h>
|
||||||
#include <qrunnable.h>
|
#include <qrunnable.h>
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
#include <qtypes.h>
|
#include <qtypes.h>
|
||||||
|
|
@ -16,7 +17,7 @@ class ColorQuantizerOperation
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ColorQuantizerOperation(QUrl* source, qreal depth, qreal rescaleSize);
|
explicit ColorQuantizerOperation(QUrl* source, qreal depth, QRect imageRect, qreal rescaleSize);
|
||||||
|
|
||||||
void run() override;
|
void run() override;
|
||||||
void tryCancel();
|
void tryCancel();
|
||||||
|
|
@ -44,6 +45,7 @@ private:
|
||||||
QList<QColor> colors;
|
QList<QColor> colors;
|
||||||
QUrl* source;
|
QUrl* source;
|
||||||
qreal maxDepth;
|
qreal maxDepth;
|
||||||
|
QRect imageRect;
|
||||||
qreal rescaleSize;
|
qreal rescaleSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -78,6 +80,13 @@ class ColorQuantizer
|
||||||
/// binary split of the color space
|
/// binary split of the color space
|
||||||
Q_PROPERTY(qreal depth READ depth WRITE setDepth NOTIFY depthChanged);
|
Q_PROPERTY(qreal depth READ depth WRITE setDepth NOTIFY depthChanged);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
/// Rectangle that the source image is cropped to.
|
||||||
|
///
|
||||||
|
/// Can be set to `undefined` to reset.
|
||||||
|
Q_PROPERTY(QRect imageRect READ imageRect WRITE setImageRect RESET resetImageRect NOTIFY imageRectChanged);
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
/// The size to rescale the image to, when rescaleSize is 0 then no scaling will be done.
|
/// The size to rescale the image to, when rescaleSize is 0 then no scaling will be done.
|
||||||
/// > [!NOTE] Results from color quantization doesn't suffer much when rescaling, it's
|
/// > [!NOTE] Results from color quantization doesn't suffer much when rescaling, it's
|
||||||
/// > reccommended to rescale, otherwise the quantization process will take much longer.
|
/// > reccommended to rescale, otherwise the quantization process will take much longer.
|
||||||
|
|
@ -97,6 +106,10 @@ public:
|
||||||
[[nodiscard]] qreal depth() const { return this->mDepth; }
|
[[nodiscard]] qreal depth() const { return this->mDepth; }
|
||||||
void setDepth(qreal depth);
|
void setDepth(qreal depth);
|
||||||
|
|
||||||
|
[[nodiscard]] QRect imageRect() const { return this->mImageRect; }
|
||||||
|
void setImageRect(QRect imageRect);
|
||||||
|
void resetImageRect();
|
||||||
|
|
||||||
[[nodiscard]] qreal rescaleSize() const { return this->mRescaleSize; }
|
[[nodiscard]] qreal rescaleSize() const { return this->mRescaleSize; }
|
||||||
void setRescaleSize(int rescaleSize);
|
void setRescaleSize(int rescaleSize);
|
||||||
|
|
||||||
|
|
@ -104,6 +117,7 @@ signals:
|
||||||
void colorsChanged();
|
void colorsChanged();
|
||||||
void sourceChanged();
|
void sourceChanged();
|
||||||
void depthChanged();
|
void depthChanged();
|
||||||
|
void imageRectChanged();
|
||||||
void rescaleSizeChanged();
|
void rescaleSizeChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
@ -117,6 +131,7 @@ private:
|
||||||
ColorQuantizerOperation* liveOperation = nullptr;
|
ColorQuantizerOperation* liveOperation = nullptr;
|
||||||
QUrl mSource;
|
QUrl mSource;
|
||||||
qreal mDepth = 0;
|
qreal mDepth = 0;
|
||||||
|
QRect mImageRect;
|
||||||
qreal mRescaleSize = 0;
|
qreal mRescaleSize = 0;
|
||||||
|
|
||||||
Q_OBJECT_BINDABLE_PROPERTY(
|
Q_OBJECT_BINDABLE_PROPERTY(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue