KIconThemes

kiconeffect.cpp
1 /* vi: ts=8 sts=4 sw=4
2 
3  This file is part of the KDE project, module kdecore.
4  SPDX-FileCopyrightText: 2000 Geert Jansen <[email protected]>
5  SPDX-FileCopyrightText: 2007 Daniel M. Duley <[email protected]>
6 
7  with minor additions and based on ideas from
8  SPDX-FileContributor: Torsten Rahn <[email protected]>
9 
10  SPDX-License-Identifier: LGPL-2.0-only
11 */
12 
13 #include "kiconeffect.h"
14 #include "debug.h"
15 
16 #include <KColorScheme>
17 #include <KConfigGroup>
18 #include <kicontheme.h>
19 
20 #include <QDebug>
21 #include <QSysInfo>
22 
23 #include <qplatformdefs.h>
24 
25 #include <math.h>
26 
27 class KIconEffectPrivate
28 {
29 public:
30  // http://en.cppreference.com/w/cpp/language/zero_initialization
31  KIconEffectPrivate()
32  : effect{{}}
33  , value{{}}
34  , color{{}}
35  , trans{{}}
36  , key{{}}
37  , color2{{}}
38  {
39  }
40 
41 public:
48 };
49 
51  : d(new KIconEffectPrivate)
52 {
53  init();
54 }
55 
56 KIconEffect::~KIconEffect() = default;
57 
59 {
60  KSharedConfig::Ptr config = KSharedConfig::openConfig();
61 
62  int i;
63  int j;
64  int effect = -1;
65  // FIXME: this really should be using KIconLoader::metaObject() to guarantee synchronization
66  // performance wise it's also practically guaranteed to be faster
67  QStringList groups;
68  groups += QStringLiteral("Desktop");
69  groups += QStringLiteral("Toolbar");
70  groups += QStringLiteral("MainToolbar");
71  groups += QStringLiteral("Small");
72  groups += QStringLiteral("Panel");
73  groups += QStringLiteral("Dialog");
74 
75  QStringList states;
76  states += QStringLiteral("Default");
77  states += QStringLiteral("Active");
78  states += QStringLiteral("Disabled");
79 
82  QString _togray(QStringLiteral("togray"));
83  QString _colorize(QStringLiteral("colorize"));
84  QString _desaturate(QStringLiteral("desaturate"));
85  QString _togamma(QStringLiteral("togamma"));
86  QString _none(QStringLiteral("none"));
87  QString _tomonochrome(QStringLiteral("tomonochrome"));
88 
89  for (it = groups.constBegin(), i = 0; it != groups.constEnd(); ++it, ++i) {
90  // Default effects
91  d->effect[i][0] = NoEffect;
92  d->effect[i][1] = ((i == 0) || (i == 4)) ? ToGamma : NoEffect;
93  d->effect[i][2] = ToGray;
94 
95  d->trans[i][0] = false;
96  d->trans[i][1] = false;
97  d->trans[i][2] = true;
98  d->value[i][0] = 1.0;
99  d->value[i][1] = ((i == 0) || (i == 4)) ? 0.7 : 1.0;
100  d->value[i][2] = 1.0;
101  d->color[i][0] = QColor(144, 128, 248);
102  d->color[i][1] = QColor(169, 156, 255);
103  d->color[i][2] = QColor(34, 202, 0);
104  d->color2[i][0] = QColor(0, 0, 0);
105  d->color2[i][1] = QColor(0, 0, 0);
106  d->color2[i][2] = QColor(0, 0, 0);
107 
108  KConfigGroup cg(config, *it + QStringLiteral("Icons"));
109  for (it2 = states.constBegin(), j = 0; it2 != states.constEnd(); ++it2, ++j) {
110  QString tmp = cg.readEntry(*it2 + QStringLiteral("Effect"), QString());
111  if (tmp == _togray) {
112  effect = ToGray;
113  } else if (tmp == _colorize) {
114  effect = Colorize;
115  } else if (tmp == _desaturate) {
116  effect = DeSaturate;
117  } else if (tmp == _togamma) {
118  effect = ToGamma;
119  } else if (tmp == _tomonochrome) {
120  effect = ToMonochrome;
121  } else if (tmp == _none) {
122  effect = NoEffect;
123  } else {
124  continue;
125  }
126  if (effect != -1) {
127  d->effect[i][j] = effect;
128  }
129  d->value[i][j] = cg.readEntry(*it2 + QStringLiteral("Value"), 0.0);
130  d->color[i][j] = cg.readEntry(*it2 + QStringLiteral("Color"), QColor());
131  d->color2[i][j] = cg.readEntry(*it2 + QStringLiteral("Color2"), QColor());
132  d->trans[i][j] = cg.readEntry(*it2 + QStringLiteral("SemiTransparent"), false);
133  }
134  }
135 }
136 
137 bool KIconEffect::hasEffect(int group, int state) const
138 {
139  if (group < 0 || group >= KIconLoader::LastGroup //
140  || state < 0 || state >= KIconLoader::LastState) {
141  return false;
142  }
143 
144  return d->effect[group][state] != NoEffect;
145 }
146 
147 QString KIconEffect::fingerprint(int group, int state) const
148 {
149  if (group < 0 || group >= KIconLoader::LastGroup //
150  || state < 0 || state >= KIconLoader::LastState) {
151  return QString();
152  }
153 
154  QString cached = d->key[group][state];
155  if (cached.isEmpty()) {
156  QString tmp;
157  cached = tmp.setNum(d->effect[group][state]);
158  cached += QLatin1Char(':');
159  cached += tmp.setNum(d->value[group][state]);
160  cached += QLatin1Char(':');
161  cached += d->trans[group][state] ? QLatin1String("trans") : QLatin1String("notrans");
162  if (d->effect[group][state] == Colorize || d->effect[group][state] == ToMonochrome) {
163  cached += QLatin1Char(':');
164  cached += d->color[group][state].name();
165  }
166  if (d->effect[group][state] == ToMonochrome) {
167  cached += QLatin1Char(':');
168  cached += d->color2[group][state].name();
169  }
170 
171  d->key[group][state] = cached;
172  }
173 
174  return cached;
175 }
176 
177 QImage KIconEffect::apply(const QImage &image, int group, int state) const
178 {
179  if (state >= KIconLoader::LastState) {
180  qCWarning(KICONTHEMES) << "Invalid icon state:" << state << ", should be one of KIconLoader::States";
181  return image;
182  }
183  if (group >= KIconLoader::LastGroup) {
184  qCWarning(KICONTHEMES) << "Invalid icon group:" << group << ", should be one of KIconLoader::Group";
185  return image;
186  }
187  return apply(image, d->effect[group][state], d->value[group][state], d->color[group][state], d->color2[group][state], d->trans[group][state]);
188 }
189 
190 QImage KIconEffect::apply(const QImage &image, int effect, float value, const QColor &col, bool trans) const
191 {
192  return apply(image, effect, value, col, KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
193 }
194 
195 QImage KIconEffect::apply(const QImage &img, int effect, float value, const QColor &col, const QColor &col2, bool trans) const
196 {
197  QImage image = img;
198  if (effect >= LastEffect) {
199  qCWarning(KICONTHEMES) << "Invalid icon effect:" << effect << ", should be one of KIconLoader::Effects";
200  return image;
201  }
202  if (value > 1.0) {
203  value = 1.0;
204  } else if (value < 0.0) {
205  value = 0.0;
206  }
207  switch (effect) {
208  case ToGray:
209  toGray(image, value);
210  break;
211  case DeSaturate:
212  deSaturate(image, value);
213  break;
214  case Colorize:
215  colorize(image, col, value);
216  break;
217  case ToGamma:
218  toGamma(image, value);
219  break;
220  case ToMonochrome:
221  toMonochrome(image, col, col2, value);
222  break;
223  }
224  if (trans == true) {
225  semiTransparent(image);
226  }
227  return image;
228 }
229 
230 QPixmap KIconEffect::apply(const QPixmap &pixmap, int group, int state) const
231 {
232  if (state >= KIconLoader::LastState) {
233  qCWarning(KICONTHEMES) << "Invalid icon state:" << state << ", should be one of KIconLoader::States";
234  return pixmap;
235  }
236  if (group >= KIconLoader::LastGroup) {
237  qCWarning(KICONTHEMES) << "Invalid icon group:" << group << ", should be one of KIconLoader::Group";
238  return pixmap;
239  }
240  return apply(pixmap, d->effect[group][state], d->value[group][state], d->color[group][state], d->color2[group][state], d->trans[group][state]);
241 }
242 
243 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value, const QColor &col, bool trans) const
244 {
245  return apply(pixmap, effect, value, col, KColorScheme(QPalette::Active, KColorScheme::View).background().color(), trans);
246 }
247 
248 QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value, const QColor &col, const QColor &col2, bool trans) const
249 {
250  QPixmap result;
251 
252  if (effect >= LastEffect) {
253  qCWarning(KICONTHEMES) << "Invalid icon effect:" << effect << ", should be one of KIconLoader::Effects";
254  return result;
255  }
256 
257  if ((trans == true) && (effect == NoEffect)) {
258  result = pixmap;
259  semiTransparent(result);
260  } else if (effect != NoEffect) {
261  QImage tmpImg = pixmap.toImage();
262  tmpImg = apply(tmpImg, effect, value, col, col2, trans);
263  result = QPixmap::fromImage(tmpImg);
264  } else {
265  result = pixmap;
266  }
267 
268  return result;
269 }
270 
271 struct KIEImgEdit {
272  QImage &img;
273  QVector<QRgb> colors;
274  unsigned int *data;
275  unsigned int pixels;
276 
277  KIEImgEdit(QImage &_img)
278  : img(_img)
279  {
280  if (img.depth() > 8) {
281  // Code using data and pixels assumes that the pixels are stored
282  // in 32bit values and that the image is not premultiplied
283  if ((img.format() != QImage::Format_ARGB32) //
284  && (img.format() != QImage::Format_RGB32)) {
286  }
287  data = (unsigned int *)img.bits();
288  pixels = img.width() * img.height();
289  } else {
290  pixels = img.colorCount();
291  colors = img.colorTable();
292  data = (unsigned int *)colors.data();
293  }
294  }
295 
296  ~KIEImgEdit()
297  {
298  if (img.depth() <= 8) {
299  img.setColorTable(colors);
300  }
301  }
302 
303  KIEImgEdit(const KIEImgEdit &) = delete;
304  KIEImgEdit &operator=(const KIEImgEdit &) = delete;
305 };
306 
307 // Taken from KImageEffect. We don't want to link kdecore to kdeui! As long
308 // as this code is not too big, it doesn't seem much of a problem to me.
309 
310 void KIconEffect::toGray(QImage &img, float value)
311 {
312  if (value == 0.0) {
313  return;
314  }
315 
316  KIEImgEdit ii(img);
317  QRgb *data = ii.data;
318  QRgb *end = data + ii.pixels;
319 
320  unsigned char gray;
321  if (value == 1.0) {
322  while (data != end) {
323  gray = qGray(*data);
324  *data = qRgba(gray, gray, gray, qAlpha(*data));
325  ++data;
326  }
327  } else {
328  unsigned char val = (unsigned char)(255.0 * value);
329  while (data != end) {
330  gray = qGray(*data);
331  *data = qRgba((val * gray + (0xFF - val) * qRed(*data)) >> 8,
332  (val * gray + (0xFF - val) * qGreen(*data)) >> 8,
333  (val * gray + (0xFF - val) * qBlue(*data)) >> 8,
334  qAlpha(*data));
335  ++data;
336  }
337  }
338 }
339 
340 void KIconEffect::colorize(QImage &img, const QColor &col, float value)
341 {
342  if (value == 0.0) {
343  return;
344  }
345 
346  KIEImgEdit ii(img);
347  QRgb *data = ii.data;
348  QRgb *end = data + ii.pixels;
349 
350  float rcol = col.red();
351  float gcol = col.green();
352  float bcol = col.blue();
353  unsigned char red;
354  unsigned char green;
355  unsigned char blue;
356  unsigned char gray;
357  unsigned char val = (unsigned char)(255.0 * value);
358  while (data != end) {
359  gray = qGray(*data);
360  if (gray < 128) {
361  red = static_cast<unsigned char>(rcol / 128 * gray);
362  green = static_cast<unsigned char>(gcol / 128 * gray);
363  blue = static_cast<unsigned char>(bcol / 128 * gray);
364  } else if (gray > 128) {
365  red = static_cast<unsigned char>((gray - 128) * (2 - rcol / 128) + rcol - 1);
366  green = static_cast<unsigned char>((gray - 128) * (2 - gcol / 128) + gcol - 1);
367  blue = static_cast<unsigned char>((gray - 128) * (2 - bcol / 128) + bcol - 1);
368  } else {
369  red = static_cast<unsigned char>(rcol);
370  green = static_cast<unsigned char>(gcol);
371  blue = static_cast<unsigned char>(bcol);
372  }
373 
374  *data = qRgba((val * red + (0xFF - val) * qRed(*data)) >> 8,
375  (val * green + (0xFF - val) * qGreen(*data)) >> 8,
376  (val * blue + (0xFF - val) * qBlue(*data)) >> 8,
377  qAlpha(*data));
378  ++data;
379  }
380 }
381 
382 void KIconEffect::toMonochrome(QImage &img, const QColor &black, const QColor &white, float value)
383 {
384  if (value == 0.0) {
385  return;
386  }
387 
388  KIEImgEdit ii(img);
389  QRgb *data = ii.data;
390  QRgb *end = data + ii.pixels;
391 
392  // Step 1: determine the average brightness
393  double values = 0.0;
394  double sum = 0.0;
395  bool grayscale = true;
396  while (data != end) {
397  sum += qGray(*data) * qAlpha(*data) + 255 * (255 - qAlpha(*data));
398  values += 255;
399  if ((qRed(*data) != qGreen(*data)) || (qGreen(*data) != qBlue(*data))) {
400  grayscale = false;
401  }
402  ++data;
403  }
404  double medium = sum / values;
405 
406  // Step 2: Modify the image
407  unsigned char val = (unsigned char)(255.0 * value);
408  int rw = white.red();
409  int gw = white.green();
410  int bw = white.blue();
411  int rb = black.red();
412  int gb = black.green();
413  int bb = black.blue();
414  data = ii.data;
415 
416  if (grayscale) {
417  while (data != end) {
418  if (qRed(*data) <= medium) {
419  *data = qRgba((val * rb + (0xFF - val) * qRed(*data)) >> 8,
420  (val * gb + (0xFF - val) * qGreen(*data)) >> 8,
421  (val * bb + (0xFF - val) * qBlue(*data)) >> 8,
422  qAlpha(*data));
423  } else {
424  *data = qRgba((val * rw + (0xFF - val) * qRed(*data)) >> 8,
425  (val * gw + (0xFF - val) * qGreen(*data)) >> 8,
426  (val * bw + (0xFF - val) * qBlue(*data)) >> 8,
427  qAlpha(*data));
428  }
429  ++data;
430  }
431  } else {
432  while (data != end) {
433  if (qGray(*data) <= medium) {
434  *data = qRgba((val * rb + (0xFF - val) * qRed(*data)) >> 8,
435  (val * gb + (0xFF - val) * qGreen(*data)) >> 8,
436  (val * bb + (0xFF - val) * qBlue(*data)) >> 8,
437  qAlpha(*data));
438  } else {
439  *data = qRgba((val * rw + (0xFF - val) * qRed(*data)) >> 8,
440  (val * gw + (0xFF - val) * qGreen(*data)) >> 8,
441  (val * bw + (0xFF - val) * qBlue(*data)) >> 8,
442  qAlpha(*data));
443  }
444  ++data;
445  }
446  }
447 }
448 
449 void KIconEffect::deSaturate(QImage &img, float value)
450 {
451  if (value == 0.0) {
452  return;
453  }
454 
455  KIEImgEdit ii(img);
456  QRgb *data = ii.data;
457  QRgb *end = data + ii.pixels;
458 
459  QColor color;
460  int h;
461  int s;
462  int v;
463  while (data != end) {
464  color.setRgb(*data);
465  color.getHsv(&h, &s, &v);
466  color.setHsv(h, (int)(s * (1.0 - value) + 0.5), v);
467  *data = qRgba(color.red(), color.green(), color.blue(), qAlpha(*data));
468  ++data;
469  }
470 }
471 
472 void KIconEffect::toGamma(QImage &img, float value)
473 {
474  KIEImgEdit ii(img);
475  QRgb *data = ii.data;
476  QRgb *end = data + ii.pixels;
477 
478  float gamma = 1 / (2 * value + 0.5);
479  while (data != end) {
480  *data = qRgba(static_cast<unsigned char>(pow(static_cast<float>(qRed(*data)) / 255, gamma) * 255),
481  static_cast<unsigned char>(pow(static_cast<float>(qGreen(*data)) / 255, gamma) * 255),
482  static_cast<unsigned char>(pow(static_cast<float>(qBlue(*data)) / 255, gamma) * 255),
483  qAlpha(*data));
484  ++data;
485  }
486 }
487 
489 {
490  if (img.depth() == 32) {
493  }
494  int width = img.width();
495  int height = img.height();
496 
497  unsigned char *line;
498  for (int y = 0; y < height; ++y) {
500  line = img.scanLine(y);
501  } else {
502  line = img.scanLine(y) + 3;
503  }
504  for (int x = 0; x < width; ++x) {
505  *line >>= 1;
506  line += 4;
507  }
508  }
509  } else if (img.depth() == 8) {
510  // not running on 8 bit, we can safely install a new colorTable
511  QVector<QRgb> colorTable = img.colorTable();
512  for (int i = 0; i < colorTable.size(); ++i) {
513  colorTable[i] = (colorTable[i] & 0x00ffffff) | ((colorTable[i] & 0xfe000000) >> 1);
514  }
515  img.setColorTable(colorTable);
516  } else {
517  // Insert transparent pixel into the clut.
518  int transColor = -1;
519 
520  // search for a color that is already transparent
521  for (int x = 0; x < img.colorCount(); ++x) {
522  // try to find already transparent pixel
523  if (qAlpha(img.color(x)) < 127) {
524  transColor = x;
525  break;
526  }
527  }
528 
529  // FIXME: image must have transparency
530  if (transColor < 0 || transColor >= img.colorCount()) {
531  return;
532  }
533 
534  img.setColor(transColor, 0);
535  unsigned char *line;
536  if (img.depth() == 8) {
537  for (int y = 0; y < img.height(); ++y) {
538  line = img.scanLine(y);
539  for (int x = (y % 2); x < img.width(); x += 2) {
540  line[x] = transColor;
541  }
542  }
543  } else {
544  const bool setOn = (transColor != 0);
545  if (img.format() == QImage::Format_MonoLSB) {
546  for (int y = 0; y < img.height(); ++y) {
547  line = img.scanLine(y);
548  for (int x = (y % 2); x < img.width(); x += 2) {
549  if (!setOn) {
550  *(line + (x >> 3)) &= ~(1 << (x & 7));
551  } else {
552  *(line + (x >> 3)) |= (1 << (x & 7));
553  }
554  }
555  }
556  } else {
557  for (int y = 0; y < img.height(); ++y) {
558  line = img.scanLine(y);
559  for (int x = (y % 2); x < img.width(); x += 2) {
560  if (!setOn) {
561  *(line + (x >> 3)) &= ~(1 << (7 - (x & 7)));
562  } else {
563  *(line + (x >> 3)) |= (1 << (7 - (x & 7)));
564  }
565  }
566  }
567  }
568  }
569  }
570 }
571 
573 {
574  QImage img = pix.toImage();
575  semiTransparent(img);
576  pix = QPixmap::fromImage(img);
577 }
578 
580 {
581  int w = src.width();
582  int h = src.height();
583 
584  QImage dst(w * 2, h * 2, src.format());
585 
586  if (src.depth() == 1) {
587  qWarning() << "image depth 1 not supported";
588  return QImage();
589  }
590 
591  int x;
592  int y;
593  if (src.depth() == 32) {
594  QRgb *l1;
595  QRgb *l2;
596  for (y = 0; y < h; ++y) {
597  l1 = (QRgb *)src.scanLine(y);
598  l2 = (QRgb *)dst.scanLine(y * 2);
599  for (x = 0; x < w; ++x) {
600  l2[x * 2] = l2[x * 2 + 1] = l1[x];
601  }
602  memcpy(dst.scanLine(y * 2 + 1), l2, dst.bytesPerLine());
603  }
604  } else {
605  for (x = 0; x < src.colorCount(); ++x) {
606  dst.setColor(x, src.color(x));
607  }
608 
609  const unsigned char *l1;
610  unsigned char *l2;
611  for (y = 0; y < h; ++y) {
612  l1 = src.scanLine(y);
613  l2 = dst.scanLine(y * 2);
614  for (x = 0; x < w; ++x) {
615  l2[x * 2] = l1[x];
616  l2[x * 2 + 1] = l1[x];
617  }
618  memcpy(dst.scanLine(y * 2 + 1), l2, dst.bytesPerLine());
619  }
620  }
621  return dst;
622 }
623 
624 void KIconEffect::overlay(QImage &src, QImage &overlay)
625 {
626  if (src.depth() != overlay.depth()) {
627  qWarning() << "Image depth src (" << src.depth() << ") != overlay "
628  << "(" << overlay.depth() << ")!";
629  return;
630  }
631  if (src.size() != overlay.size()) {
632  qWarning() << "Image size src != overlay";
633  return;
634  }
637  }
638 
639  if (overlay.format() == QImage::Format_RGB32) {
640  qWarning() << "Overlay doesn't have alpha buffer!";
641  return;
642  } else if (overlay.format() == QImage::Format_ARGB32_Premultiplied) {
643  overlay = overlay.convertToFormat(QImage::Format_ARGB32);
644  }
645 
646  int i;
647  int j;
648 
649  // We don't do 1 bpp
650 
651  if (src.depth() == 1) {
652  qWarning() << "1bpp not supported!";
653  return;
654  }
655 
656  // Overlay at 8 bpp doesn't use alpha blending
657 
658  if (src.depth() == 8) {
659  if (src.colorCount() + overlay.colorCount() > 255) {
660  qWarning() << "Too many colors in src + overlay!";
661  return;
662  }
663 
664  // Find transparent pixel in overlay
665  int trans;
666  for (trans = 0; trans < overlay.colorCount(); trans++) {
667  if (qAlpha(overlay.color(trans)) == 0) {
668  qWarning() << "transparent pixel found at " << trans;
669  break;
670  }
671  }
672  if (trans == overlay.colorCount()) {
673  qWarning() << "transparent pixel not found!";
674  return;
675  }
676 
677  // Merge color tables
678  int nc = src.colorCount();
679  src.setColorCount(nc + overlay.colorCount());
680  for (i = 0; i < overlay.colorCount(); ++i) {
681  src.setColor(nc + i, overlay.color(i));
682  }
683 
684  // Overwrite nontransparent pixels.
685  unsigned char *oline;
686  unsigned char *sline;
687  for (i = 0; i < src.height(); ++i) {
688  oline = overlay.scanLine(i);
689  sline = src.scanLine(i);
690  for (j = 0; j < src.width(); ++j) {
691  if (oline[j] != trans) {
692  sline[j] = oline[j] + nc;
693  }
694  }
695  }
696  }
697 
698  // Overlay at 32 bpp does use alpha blending
699 
700  if (src.depth() == 32) {
701  QRgb *oline;
702  QRgb *sline;
703  int r1;
704  int g1;
705  int b1;
706  int a1;
707  int r2;
708  int g2;
709  int b2;
710  int a2;
711 
712  for (i = 0; i < src.height(); ++i) {
713  oline = (QRgb *)overlay.scanLine(i);
714  sline = (QRgb *)src.scanLine(i);
715 
716  for (j = 0; j < src.width(); ++j) {
717  r1 = qRed(oline[j]);
718  g1 = qGreen(oline[j]);
719  b1 = qBlue(oline[j]);
720  a1 = qAlpha(oline[j]);
721 
722  r2 = qRed(sline[j]);
723  g2 = qGreen(sline[j]);
724  b2 = qBlue(sline[j]);
725  a2 = qAlpha(sline[j]);
726 
727  r2 = (a1 * r1 + (0xff - a1) * r2) >> 8;
728  g2 = (a1 * g1 + (0xff - a1) * g2) >> 8;
729  b2 = (a1 * b1 + (0xff - a1) * b2) >> 8;
730  a2 = qMax(a1, a2);
731 
732  sline[j] = qRgba(r2, g2, b2, a2);
733  }
734  }
735  }
736 }
QString readEntry(const char *key, const char *aDefault=nullptr) const
static void semiTransparent(QImage &image)
Renders an image semi-transparent.
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
int height() const const
int depth() const const
QImage::Format format() const const
int red() const const
static void overlay(QImage &src, QImage &overlay)
Overlays an image with an other image.
QRgb color(int i) const const
QList::const_iterator constBegin() const const
void setColorCount(int colorCount)
void setHsv(int h, int s, int v, int a)
T * data()
QImage doublePixels(const QImage &src) const
Returns an image twice as large, consisting of 2x2 pixels.
QImage apply(const QImage &src, int group, int state) const
Applies an effect to an image.
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
KIconEffect()
Create a new KIconEffect.
Definition: kiconeffect.cpp:50
@ LastGroup
Last group.
Definition: kiconloader.h:147
static void colorize(QImage &image, const QColor &col, float value)
Colorizes an image with a specific color.
void init()
Rereads configuration.
Definition: kiconeffect.cpp:58
QString & setNum(short n, int base)
static void toMonochrome(QImage &image, const QColor &black, const QColor &white, float value)
Produces a monochrome icon with a given foreground and background color.
static void toGamma(QImage &image, float value)
Changes the gamma value of an image.
bool isEmpty() const const
uchar * bits()
QImage convertToFormat(QImage::Format format, Qt::ImageConversionFlags flags) const &const
int green() const const
int bytesPerLine() const const
static void deSaturate(QImage &image, float value)
Desaturates an image.
QVector< QRgb > colorTable() const const
QSize size() const const
KSharedConfigPtr config()
QImage toImage() const const
uchar * scanLine(int i)
typedef ConstIterator
QString fingerprint(int group, int state) const
Returns a fingerprint for the effect by encoding the given group and state into a QString.
void setColor(int index, QRgb colorValue)
QList::const_iterator constEnd() const const
@ LastState
Last state (last constant)
Definition: kiconloader.h:180
void setRgb(int r, int g, int b, int a)
int blue() const const
bool hasEffect(int group, int state) const
Tests whether an effect has been configured for the given icon group.
int size() const const
static void toGray(QImage &image, float value)
Tints an image gray.
void getHsv(int *h, int *s, int *v, int *a) const const
int colorCount() const const
QVector< V > values(const QMultiHash< K, V > &c)
void setColorTable(const QVector< QRgb > colors)
int width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Sep 26 2023 03:58:09 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.