Kirigami2

imagecolors.h
1/*
2 * SPDX-FileCopyrightText: 2020 Marco Martin <mart@kde.org>
3 * SPDX-FileCopyrightText: 2024 ivan tkachenko <me@ratijas.tk>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#pragma once
9
10#include <QColor>
11#include <QFuture>
12#include <QImage>
13#include <QObject>
14#include <QPointer>
15#include <QQuickItem>
16#include <QQuickItemGrabResult>
17#include <QQuickWindow>
18
19#include <platform/colorutils.h>
20
21struct PaletteSwatch {
22 Q_GADGET
23 QML_VALUE_TYPE(imageColorsPaletteSwatch)
24
25 Q_PROPERTY(qreal ratio READ ratio FINAL)
26 Q_PROPERTY(QColor color READ color FINAL)
27 Q_PROPERTY(QColor contrastColor READ contrastColor FINAL)
28
29public:
30 explicit PaletteSwatch();
31 explicit PaletteSwatch(qreal ratio, const QColor &color, const QColor &contrastColor);
32
33 qreal ratio() const;
34 const QColor &color() const;
35 const QColor &contrastColor() const;
36
37 bool operator==(const PaletteSwatch &other) const;
38
39private:
40 qreal m_ratio;
41 QColor m_color;
42 QColor m_contrastColor;
43};
44
45struct ImageData {
46 struct colorStat {
47 QList<QRgb> colors;
48 QRgb centroid = 0;
49 qreal ratio = 0;
50 };
51
52 struct colorSet {
53 QColor average;
54 QColor text;
55 QColor background;
56 QColor highlight;
57 };
58
59 QList<QRgb> m_samples;
60 QList<colorStat> m_clusters;
61 QList<PaletteSwatch> m_palette;
62
63 bool m_darkPalette = true;
64 QColor m_dominant = Qt::transparent;
65 QColor m_dominantContrast;
66 QColor m_average;
67 QColor m_highlight;
68
69 QColor m_closestToBlack;
70 QColor m_closestToWhite;
71};
72
73/**
74 * Extracts the dominant colors from an element or an image and exports it to a color palette.
75 */
76class ImageColors : public QObject
77{
79 QML_ELEMENT
80 /**
81 * The source from which colors should be extracted from.
82 *
83 * `source` can be one of the following:
84 * * Item
85 * * QImage
86 * * QIcon
87 * * Icon name
88 *
89 * Note that an Item's color palette will only be extracted once unless you
90 * call `update()`, regardless of how the item hanges.
91 */
92 Q_PROPERTY(QVariant source READ source WRITE setSource NOTIFY sourceChanged FINAL)
93
94 /**
95 * A list of colors and related information about then.
96 *
97 * Each list item has the following properties:
98 * * `color`: The color of the list item.
99 * * `ratio`: How dominant the color is in the source image.
100 * * `contrastingColor`: The color from the source image that's closest to the inverse of `color`.
101 *
102 * The list is sorted by `ratio`; the first element is the most
103 * dominant color in the source image and the last element is the
104 * least dominant color of the image.
105 *
106 * \note K-means clustering is used to extract these colors; see https://en.wikipedia.org/wiki/K-means_clustering.
107 */
108 Q_PROPERTY(QList<PaletteSwatch> palette READ palette NOTIFY paletteChanged FINAL)
109
110 /**
111 * Information whether the palette is towards a light or dark color
112 * scheme, possible values are:
113 * * ColorUtils.Light
114 * * ColorUtils.Dark
115 */
116 Q_PROPERTY(ColorUtils::Brightness paletteBrightness READ paletteBrightness NOTIFY paletteChanged FINAL)
117
118 /**
119 * The average color of the source image.
120 */
121 Q_PROPERTY(QColor average READ average NOTIFY paletteChanged FINAL)
122
123 /**
124 * The dominant color of the source image.
125 *
126 * The dominant color of the image is the color of the largest
127 * cluster in the image.
128 *
129 * \sa https://en.wikipedia.org/wiki/K-means_clustering
130 */
131 Q_PROPERTY(QColor dominant READ dominant NOTIFY paletteChanged FINAL)
132
133 /**
134 * Suggested "contrasting" color to the dominant one. It's the color in the palette nearest to the negative of the dominant
135 */
136 Q_PROPERTY(QColor dominantContrast READ dominantContrast NOTIFY paletteChanged FINAL)
137
138 /**
139 * An accent color extracted from the source image.
140 *
141 * The accent color is the color cluster with the highest CIELAB
142 * chroma in the source image.
143 *
144 * \sa https://en.wikipedia.org/wiki/Colorfulness#Chroma
145 */
146 Q_PROPERTY(QColor highlight READ highlight NOTIFY paletteChanged FINAL)
147
148 /**
149 * A color suitable for rendering text and other foreground
150 * over the source image.
151 *
152 * On dark items, this will be the color closest to white in
153 * the image if it's light enough, or a bright gray otherwise.
154 * On light items, this will be the color closest to black in
155 * the image if it's dark enough, or a dark gray otherwise.
156 */
157 Q_PROPERTY(QColor foreground READ foreground NOTIFY paletteChanged FINAL)
158
159 /**
160 * A color suitable for rendering a background behind the
161 * source image.
162 *
163 * On dark items, this will be the color closest to black in the
164 * image if it's dark enough, or a dark gray otherwise.
165 * On light items, this will be the color closest to white
166 * in the image if it's light enough, or a bright gray otherwise.
167 */
168 Q_PROPERTY(QColor background READ background NOTIFY paletteChanged FINAL)
169
170 /**
171 * The lightest color of the source image.
172 */
173 Q_PROPERTY(QColor closestToWhite READ closestToWhite NOTIFY paletteChanged FINAL)
174
175 /**
176 * The darkest color of the source image.
177 */
178 Q_PROPERTY(QColor closestToBlack READ closestToBlack NOTIFY paletteChanged FINAL)
179
180 /**
181 * The value to return when palette is not available, e.g. when
182 * ImageColors is still computing it or the source is invalid.
183 */
184 Q_PROPERTY(QList<PaletteSwatch> fallbackPalette MEMBER m_fallbackPalette NOTIFY fallbackPaletteChanged FINAL)
185
186 /**
187 * The value to return when paletteBrightness is not available, e.g. when
188 * ImageColors is still computing it or the source is invalid.
189 */
190 Q_PROPERTY(ColorUtils::Brightness fallbackPaletteBrightness MEMBER m_fallbackPaletteBrightness NOTIFY fallbackPaletteBrightnessChanged FINAL)
191
192 /**
193 * The value to return when average is not available, e.g. when
194 * ImageColors is still computing it or the source is invalid.
195 */
196 Q_PROPERTY(QColor fallbackAverage MEMBER m_fallbackAverage NOTIFY fallbackAverageChanged FINAL)
197
198 /**
199 * The value to return when dominant is not available, e.g. when
200 * ImageColors is still computing it or the source is invalid.
201 */
202 Q_PROPERTY(QColor fallbackDominant MEMBER m_fallbackDominant NOTIFY fallbackDominantChanged FINAL)
203
204 /**
205 * The value to return when dominantContrasting is not available, e.g. when
206 * ImageColors is still computing it or the source is invalid.
207 */
208 Q_PROPERTY(QColor fallbackDominantContrasting MEMBER m_fallbackDominantContrasting NOTIFY fallbackDominantContrastingChanged FINAL)
209
210 /**
211 * The value to return when highlight is not available, e.g. when
212 * ImageColors is still computing it or the source is invalid.
213 */
214 Q_PROPERTY(QColor fallbackHighlight MEMBER m_fallbackHighlight NOTIFY fallbackHighlightChanged FINAL)
215
216 /**
217 * The value to return when foreground is not available, e.g. when
218 * ImageColors is still computing it or the source is invalid.
219 */
220 Q_PROPERTY(QColor fallbackForeground MEMBER m_fallbackForeground NOTIFY fallbackForegroundChanged FINAL)
221
222 /**
223 * The value to return when background is not available, e.g. when
224 * ImageColors is still computing it or the source is invalid.
225 */
226 Q_PROPERTY(QColor fallbackBackground MEMBER m_fallbackBackground NOTIFY fallbackBackgroundChanged FINAL)
227
228public:
229 explicit ImageColors(QObject *parent = nullptr);
230 ~ImageColors() override;
231
232 void setSource(const QVariant &source);
233 QVariant source() const;
234
235 void setSourceImage(const QImage &image);
236 QImage sourceImage() const;
237
238 void setSourceItem(QQuickItem *source);
239 QQuickItem *sourceItem() const;
240
241 Q_INVOKABLE void update();
242
243 QList<PaletteSwatch> palette() const;
244 ColorUtils::Brightness paletteBrightness() const;
245 QColor average() const;
246 QColor dominant() const;
247 QColor dominantContrast() const;
248 QColor highlight() const;
249 QColor foreground() const;
250 QColor background() const;
251 QColor closestToWhite() const;
252 QColor closestToBlack() const;
253
255 void sourceChanged();
256 void paletteChanged();
257 void fallbackPaletteChanged();
258 void fallbackPaletteBrightnessChanged();
259 void fallbackAverageChanged();
260 void fallbackDominantChanged();
261 void fallbackDominantContrastingChanged();
262 void fallbackHighlightChanged();
263 void fallbackForegroundChanged();
264 void fallbackBackgroundChanged();
265
266private:
267 static inline void positionColor(QRgb rgb, QList<ImageData::colorStat> &clusters);
268 static void positionColorMP(const decltype(ImageData::m_samples) &samples, decltype(ImageData::m_clusters) &clusters, int numCore = 0);
269 static ImageData generatePalette(const QImage &sourceImage);
270
271 static double getClusterScore(const ImageData::colorStat &stat);
272 void postProcess(ImageData &imageData) const;
273
274 // Arbitrary number that seems to work well
275 static const int s_minimumSquareDistance = 32000;
276 QPointer<QQuickWindow> m_window;
277 QVariant m_source;
278 QPointer<QQuickItem> m_sourceItem;
280 QImage m_sourceImage;
281 QFutureWatcher<QImage> *m_futureSourceImageData = nullptr;
282
283 QFutureWatcher<ImageData> *m_futureImageData = nullptr;
284 ImageData m_imageData;
285
286 QList<PaletteSwatch> m_fallbackPalette;
287 ColorUtils::Brightness m_fallbackPaletteBrightness;
288 QColor m_fallbackAverage;
289 QColor m_fallbackDominant;
290 QColor m_fallbackDominantContrasting;
291 QColor m_fallbackHighlight;
292 QColor m_fallbackForeground;
293 QColor m_fallbackBackground;
294};
Utilities for processing items to obtain colors and information useful for UIs that need to adjust to...
Definition colorutils.h:21
Extracts the dominant colors from an element or an image and exports it to a color palette.
Definition imagecolors.h:77
QColor fallbackDominant
The value to return when dominant is not available, e.g.
ColorUtils::Brightness fallbackPaletteBrightness
The value to return when paletteBrightness is not available, e.g.
QML_ELEMENTQVariant source
The source from which colors should be extracted from.
Definition imagecolors.h:92
QColor foreground
A color suitable for rendering text and other foreground over the source image.
QColor closestToWhite
The lightest color of the source image.
QColor dominant
The dominant color of the source image.
QColor fallbackAverage
The value to return when average is not available, e.g.
QColor closestToBlack
The darkest color of the source image.
QColor fallbackBackground
The value to return when background is not available, e.g.
QList< PaletteSwatch > palette
A list of colors and related information about then.
QColor fallbackForeground
The value to return when foreground is not available, e.g.
QColor dominantContrast
Suggested "contrasting" color to the dominant one.
ColorUtils::Brightness paletteBrightness
Information whether the palette is towards a light or dark color scheme, possible values are:
QColor fallbackDominantContrasting
The value to return when dominantContrasting is not available, e.g.
QColor average
The average color of the source image.
QColor background
A color suitable for rendering a background behind the source image.
QList< PaletteSwatch > fallbackPalette
The value to return when palette is not available, e.g.
QColor highlight
An accent color extracted from the source image.
QColor fallbackHighlight
The value to return when highlight is not available, e.g.
Q_INVOKABLEQ_INVOKABLE
Q_OBJECTQ_OBJECT
Q_PROPERTY(...)
Q_SIGNALSQ_SIGNALS
QObject * parent() const const
transparent
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Nov 17 2024 19:26:02 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.