Add ColorUtils
ClosedPublic

Authored by cblack on Mar 19 2020, 4:40 AM.

Details

Summary

ColorUtils is a class that offers utilities for working with items and obtaining colours meaningful for UI usage, offering the following items as a start:

  • QColor averageColorForItem(QQuickItem*, int) - Obtains the average colour of an item, ignoring transparent pixels
  • Brightness brightnessForItem(QQuickItem*) - Obtains the brightness of an item
  • QColor alphaBlend(QColor foreground, QColor background) - Gets the colour of overlaying a transparent foreground on a background
  • QColor linearInterpolation(QColor, QColor, double) - Linearly interpolates between two colours
  • QColor adjustColor(QColor, adjustments) - Adjusts the color by fixed values
  • QColor scaleColor(QColor, adjustments) - Scales the color's values

Diff Detail

Repository
R169 Kirigami
Branch
cblack/colour-utils
Lint
No Linters Available
Unit
No Unit Test Coverage
Build Status
Buildable 24040
Build 24058: arc lint + arc unit
cblack created this revision.Mar 19 2020, 4:40 AM
Restricted Application added a project: Kirigami. · View Herald TranscriptMar 19 2020, 4:40 AM
Restricted Application added a subscriber: plasma-devel. · View Herald Transcript
cblack requested review of this revision.Mar 19 2020, 4:40 AM
cblack updated this revision to Diff 77972.Mar 19 2020, 4:41 AM

Add EOF newlines

cblack updated this revision to Diff 77973.Mar 19 2020, 4:43 AM

Use words instead of single letters

cblack updated this revision to Diff 77974.Mar 19 2020, 4:54 AM

Add comments to code

cblack edited the summary of this revision. (Show Details)Mar 19 2020, 4:57 AM
cblack updated this revision to Diff 77975.Mar 19 2020, 4:58 AM

Better class description

cblack updated this revision to Diff 77976.Mar 19 2020, 5:05 AM

Improve documentation comments

mart added a comment.Mar 19 2020, 9:05 AM

First of all.. I love the idea! :)

I wanted something like that, tough i had a slightly different approach.. i find the global average color usually producing a kinda washed down color (from what happens in the plasma mobile app startup screen)

For another project i needed something along the lines, and ended up using a variant of the k-means clustering technique, so you have averages of the colors grouped in clusters by frequency which can generate interesting palettes to play with (then is trivial to add a global average if really needed).
https://towardsdatascience.com/extracting-colours-from-an-image-using-k-means-clustering-9616348712be

the first implementation is there (i want a way better api for it to be integrated in kirigami tough)
https://invent.kde.org/kde/plasma-bigscreen/-/blob/master/components/imagepalette.h

src/colorutils.cpp
27

sync calls should be avoided whenever possible

cblack updated this revision to Diff 78030.Mar 19 2020, 5:25 PM

Asynchronous return values

cblack marked an inline comment as done.Mar 19 2020, 5:26 PM
cblack updated this revision to Diff 78069.Mar 20 2020, 5:42 AM

Add linear interpolation, alpha blending, colour adjustment, and colour scaling

cblack edited the summary of this revision. (Show Details)Mar 20 2020, 5:44 AM
mart requested changes to this revision.EditedMar 20 2020, 10:29 AM

I'm ok for functions that manipulate or give info for colors, but
please no item grabbing in the singlethon. item grabbing is *not* stateless

This revision now requires changes to proceed.Mar 20 2020, 10:29 AM
cblack updated this revision to Diff 78187.Mar 21 2020, 6:51 PM

Make brightnessForItem and averageColorForItem take QVariants

cblack updated this revision to Diff 78188.Mar 21 2020, 6:55 PM

Avoid leaving unused connections; effectively removing leaking state related to item grabbing

davidedmundson requested changes to this revision.Mar 21 2020, 7:16 PM
davidedmundson added a subscriber: davidedmundson.

What's your intended usecase?

Is Kirigami the right place? The original scope for that was "core application building blocks".

src/colorutils.cpp
78

Depending on use case, it might be better to take a QSGTextureProvider

then images can give you a surface directly without the blit, and you can still take composite items through a ShaderEffectSource

src/pendingvalue.h
25

Having a nested event loop called from QML code is really really dangerous.

If you want it for unit tests or something, fine.

Invokable, absolutely not.

This revision now requires changes to proceed.Mar 21 2020, 7:16 PM

What's your intended usecase?

Generating UI colours from images, icons, etc. and then applying transformations on them to make them more usable.

Examples:

  • PlaMo's splash screen uses something like this to generate a splash colour background
  • Plasma BigScreen cards also uses something like this to generate card backgrounds
  • Ikona could use this to determine what background and foreground to use for displaying icons from various icon themes at sufficient contrast
cblack updated this revision to Diff 78510.Mar 26 2020, 12:58 AM

Fix errors

mart requested changes to this revision.Apr 1 2020, 9:34 AM

still, no item grabbing

This revision now requires changes to proceed.Apr 1 2020, 9:34 AM
cblack updated this revision to Diff 79097.Apr 2 2020, 12:32 AM

Address feedback

cblack marked 2 inline comments as done.Apr 2 2020, 12:33 AM
fvogt added a subscriber: fvogt.Apr 4 2020, 4:47 PM
fvogt added inline comments.
src/colorutils.cpp
91

If item is neither of those three, it would never call pending->setValue at all

104

Is this supposed to be result->value().isValid() instead?

If no, how can pending be valid at this point`?

If yes, how can result be valid at this point? It would also mean that ready wouldn't get emitted again, which results in a leak.

cblack updated this revision to Diff 79327.Apr 4 2020, 5:33 PM
cblack marked 2 inline comments as done.

Address issues

cblack updated this revision to Diff 79333.Apr 4 2020, 6:10 PM

Rewrite PendingValue to use QFuture

mart requested changes to this revision.Apr 6 2020, 8:57 AM
mart added inline comments.
src/colorutils.h
74

*sigh* should be more clear...
what i don't want in a singleton type, and i'm not going to accept until is there, is this whole grabbing of items.

in a singleton like that, i would want uniquely small, stateless and sync functions that take QColors as input and have qcolors (or any other simple value lile ints and what not) as output, nothing else

This revision now requires changes to proceed.Apr 6 2020, 8:57 AM
mart added a comment.Apr 6 2020, 8:19 PM

thanks, almost ready to go :)

mart accepted this revision.Apr 6 2020, 8:43 PM
This revision was not accepted when it landed; it landed in state Needs Review.Apr 6 2020, 8:50 PM
Closed by commit R169:4c7780ea5cf7: Add ColorUtils (authored by cblack). · Explain Why
This revision was automatically updated to reflect the committed changes.
dfaure added a subscriber: dfaure.Apr 8 2020, 11:27 AM

Breaks compilation with Qt 5.13 too.

/data/kde/src/5/frameworks/kirigami/src/kirigamiplugin.cpp:248:122: error: invalid user-defined conversion from ‘KirigamiPlugin::registerTypes(const char*)::<lambda(QQmlEngine*, QJSEngine*)>’ to ‘QObject* (*)(QQmlEngine*, QJSEngine*)’ [-fpermissive]
  248 |     qmlRegisterSingletonType<ColorUtils>(uri, 2, 12, "ColorUtils", [](QQmlEngine*, QJSEngine*) { return new ColorUtils; });
      |                                                                                                                          ^

This overload is new in Qt 5.14.
Please use something that works with 5.12, and/or use a QT_VERSION #if.

same for Qt5.13.2
please revert or fix asap. lots of the build stack depends on kirigami

[3/5] Building CXX object src/CMakeFiles/kirigamiplugin.dir/kirigamiplugin.cpp.o
FAILED: src/CMakeFiles/kirigamiplugin.dir/kirigamiplugin.cpp.o 
/data/kde/src/5/frameworks/kirigami/src/kirigamiplugin.cpp:248:122: error: invalid user-defined conversion from ‘KirigamiPlugin::registerTypes(const char*)::<lambda(QQmlEngine*, QJSEngine*)>’ to ‘QObject* (*)(QQmlEngine*, QJSEngine*)’ [-fpermissive]
  248 |     qmlRegisterSingletonType<ColorUtils>(uri, 2, 12, "ColorUtils", [](QQmlEngine*, QJSEngine*) { return new ColorUtils; });
      |                                                                                                                          ^
/data/kde/src/5/frameworks/kirigami/src/kirigamiplugin.cpp:248:68: note: candidate is: ‘KirigamiPlugin::registerTypes(const char*)::<lambda(QQmlEngine*, QJSEngine*)>::operator ColorUtils* (*)(QQmlEngine*, QJSEngine*)() const’ <near match>
  248 |     qmlRegisterSingletonType<ColorUtils>(uri, 2, 12, "ColorUtils", [](QQmlEngine*, QJSEngine*) { return new ColorUtils; });
      |                                                                    ^
/data/kde/src/5/frameworks/kirigami/src/kirigamiplugin.cpp:248:68: note:   no known conversion from ‘ColorUtils* (*)(QQmlEngine*, QJSEngine*)’ to ‘QObject* (*)(QQmlEngine*, QJSEngine*)’
In file included from /usr/include/qt5/QtQml/qqmlengine.h:47,
                 from /usr/include/qt5/QtQml/QQmlEngine:1,
                 from /data/kde/src/5/frameworks/kirigami/src/kirigamiplugin.h:14