Mercurial > hg > svgui
comparison layer/ColourDatabase.cpp @ 1578:57a4ee52ad69 background-mode
Make nearby-colour matching a bit more sophisticated, with slightly better algorithm (we think?) and ability to insist on dark/light background
author | Chris Cannam |
---|---|
date | Fri, 24 Jan 2020 12:40:07 +0000 |
parents | ad86aa712d11 |
children |
comparison
equal
deleted
inserted
replaced
1577:2c974337f306 | 1578:57a4ee52ad69 |
---|---|
86 | 86 |
87 return -1; | 87 return -1; |
88 } | 88 } |
89 | 89 |
90 int | 90 int |
91 ColourDatabase::getNearbyColourIndex(QColor col) const | 91 ColourDatabase::getNearbyColourIndex(QColor col, WithBackgroundMode mode) const |
92 { | 92 { |
93 int index = 0; | 93 int index = -1; |
94 int closestIndex = -1; | 94 int closestIndex = -1; |
95 int closestDistance = 0; | 95 double closestDistance = 0; |
96 | 96 |
97 for (auto &c: m_colours) { | 97 for (auto &c: m_colours) { |
98 int distance = | 98 |
99 std::abs(col.red() - c.colour.red()) + | 99 ++index; |
100 std::abs(col.green() - c.colour.green()) + | 100 |
101 std::abs(col.blue() - c.colour.blue()); | 101 if (mode == WithDarkBackground && !c.darkbg) { |
102 #ifdef DEBUG_COLOUR_DATABASE | |
103 SVDEBUG << "getNearbyColourIndex: dark background requested, skipping " << c.colour.name() << endl; | |
104 #endif | |
105 continue; | |
106 } | |
107 if (mode == WithLightBackground && c.darkbg) { | |
108 #ifdef DEBUG_COLOUR_DATABASE | |
109 SVDEBUG << "getNearbyColourIndex: light background requested, skipping " << c.colour.name() << endl; | |
110 #endif | |
111 continue; | |
112 } | |
113 | |
114 // This distance formula is "one of the better low-cost | |
115 // approximations" according to | |
116 // https://en.wikipedia.org/w/index.php?title=Color_difference&oldid=936888327 | |
117 | |
118 double r1 = col.red(), r2 = c.colour.red(); | |
119 double g1 = col.green(), g2 = c.colour.green(); | |
120 double b1 = col.blue(), b2 = c.colour.blue(); | |
121 | |
122 double rav = (r1 + r2) / 2.0; | |
123 double rterm = (2.0 + rav / 256.0) * (r1 - r2) * (r1 - r2); | |
124 double gterm = 4.0 * (g1 - g2) * (g1 - g2); | |
125 double bterm = (2.0 + (255 - rav) / 256.0) * (b1 - b2) * (b1 - b2); | |
126 | |
127 double distance = sqrt(rterm + gterm + bterm); | |
128 | |
102 #ifdef DEBUG_COLOUR_DATABASE | 129 #ifdef DEBUG_COLOUR_DATABASE |
103 SVDEBUG << "getNearbyColourIndex: comparing " << c.colour.name() | 130 SVDEBUG << "getNearbyColourIndex: comparing " << c.colour.name() |
104 << " to " << col.name() << ": distance = " << distance << endl; | 131 << " to " << col.name() << ": distance = " << distance << endl; |
105 #endif | 132 #endif |
106 if (closestIndex < 0 || distance < closestDistance) { | 133 if (closestIndex < 0 || distance < closestDistance) { |
108 closestDistance = distance; | 135 closestDistance = distance; |
109 #ifdef DEBUG_COLOUR_DATABASE | 136 #ifdef DEBUG_COLOUR_DATABASE |
110 SVDEBUG << "(this is the best so far)" << endl; | 137 SVDEBUG << "(this is the best so far)" << endl; |
111 #endif | 138 #endif |
112 } | 139 } |
113 ++index; | |
114 } | 140 } |
115 | 141 |
116 #ifdef DEBUG_COLOUR_DATABASE | 142 #ifdef DEBUG_COLOUR_DATABASE |
117 SVDEBUG << "returning " << closestIndex << endl; | 143 SVDEBUG << "returning " << closestIndex << endl; |
118 #endif | 144 #endif |