[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-accessibility
Subject:    [Kde-accessibility] Icon effect for monochrome icons
From:       Gunnar Schmi Dt <gunnar () schmi-dt ! de>
Date:       2004-11-25 13:57:10
Message-ID: 200411251457.17404.gunnar () schmi-dt ! de
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


Hello,

During akademy I have experimented with some algorithms that produce 
monochrome icons from standard (colored) icons. One of the algorithms 
produces quite acceptable results, and so I have now produced patches for 
kdelibs and kdebase that add this icon effect to the list of standard icon 
sets.

Basically the algorithm works as follows: It first calculates an average 
brightness of the icon. In a second step everything darker than the 
average gets painted in the foreground color and everything lighter than 
the average gets painted in the background color.

In order to define the foreground and background color I have decided to 
produce two versions of the patch (and I would like to hear some feedback 
about which version is better suited for the inclusion in KDE 3.4):

The first version (kdelibs.diff and kdebase.diff) uses the color defined 
with the icon effect as the foreground color and the standard background 
color from the color scheme as the background color. This has the 
disadvantage that it adds a dependency between the color scheme and the 
icon theme (everytime when the color scheme changes the icons need to be 
re-loaded). The current version of this patch does simply ignore this 
additional dependency.

The second version (kdelibs2.diff and kdebase2.diff) adds an additional 
second color to the icon effect, so that both colors are defined with the 
icon effect. This has the advantage that it does not add a dependency 
between the color scheme and the icon theme, but it also requires some 
more changes to the API (i.e., the second color needs to be added).

A problem that remains with both versions is that the selected icons are 
calculated by applying some standard icon effect to the icon (The icon is 
overlaid with the color for the selected background). While this is ok in 
most situations it is not ideal for high contrast icons (where you might 
want to have full control of the resulting colors). However, in order to 
change this we would need to apply some big changes to both the algorithms 
that load the icons and to the kdecore API, so that this is not feasible 
for KDE 3.4.


In either case this icon effect does not replace the need for a high 
contrast icon theme that is useable for low-vision users. It rather is 
intended to both colorize such a high contrast icon theme in colors that 
match the color theme and for "incorporating" icons that are missing in 
the high contrast icon theme (and otherwise would be painted as they are 
with all colors).

Gunnar Schmi Dt
-- 
Co-maintainer of the KDE Accessibility Project
Maintainer of the kdeaccessibility package
http://accessibility.kde.org/

["kdebase2.diff" (text/x-diff)]

Index: kcontrol/icons/icons.cpp
===================================================================
RCS file: /home/kde/kdebase/kcontrol/icons/icons.cpp,v
retrieving revision 1.37
diff -u -p -r1.37 icons.cpp
--- kcontrol/icons/icons.cpp	22 Oct 2004 19:11:15 -0000	1.37
+++ kcontrol/icons/icons.cpp	25 Nov 2004 13:18:55 -0000
@@ -163,6 +163,9 @@ void KIconConfig::initDefaults()
     mDefaultEffect[0].color = QColor(144,128,248);
     mDefaultEffect[1].color = QColor(169,156,255);
     mDefaultEffect[2].color = QColor(34,202,0);
+    mDefaultEffect[0].color2 = QColor(0,0,0);
+    mDefaultEffect[1].color2 = QColor(0,0,0);
+    mDefaultEffect[2].color2 = QColor(0,0,0);
 
     const int defDefSizes[] = { 32, 22, 22, 16, 32 };
 
@@ -250,12 +253,15 @@ void KIconConfig::read()
 		effect = KIconEffect::ToGamma;
 	    else if (tmp == "desaturate")
 		effect = KIconEffect::DeSaturate;
+	    else if (tmp == "tomonochrome")
+		effect = KIconEffect::ToMonochrome;
 	    else if (tmp == "none")
 		effect = KIconEffect::NoEffect;
 	    else continue;
 	    mEffects[i][j].type = effect;
 	    mEffects[i][j].value = mpConfig->readDoubleNumEntry(*it2 + "Value");
 	    mEffects[i][j].color = mpConfig->readColorEntry(*it2 + "Color");
+	    mEffects[i][j].color2 = mpConfig->readColorEntry(*it2 + "Color2");
 	    mEffects[i][j].transparant = mpConfig->readBoolEntry(*it2 + "SemiTransparent");
 	}
     }
@@ -309,7 +315,7 @@ void KIconConfig::preview(int i)
     Effect &effect = mEffects[viewedGroup][i];
 
     img = mpEffect->apply(img, effect.type,
-	    effect.value, effect.color, effect.transparant);
+	    effect.value, effect.color, effect.color2, effect.transparant);
     pm.convertFromImage(img);
     mpPreview[i]->setPixmap(pm);
 }
@@ -359,6 +365,9 @@ void KIconConfig::save()
 	    case KIconEffect::DeSaturate:
 		tmp = "desaturate";
 		break;
+	    case KIconEffect::ToMonochrome:
+		tmp = "tomonochrome";
+		break;
 	    default:
 		tmp = "none";
 		break;
@@ -366,6 +375,7 @@ void KIconConfig::save()
 	    mpConfig->writeEntry(*it2 + "Effect", tmp, true, true);
 	    mpConfig->writeEntry(*it2 + "Value", mEffects[i][j].value, true, true);
             mpConfig->writeEntry(*it2 + "Color", mEffects[i][j].color, true, true);
+            mpConfig->writeEntry(*it2 + "Color2", mEffects[i][j].color2, true, \
                true);
             mpConfig->writeEntry(*it2 + "SemiTransparent", \
mEffects[i][j].transparant, true, true);  }
     }
@@ -526,6 +536,7 @@ KIconEffectSetupDialog::KIconEffectSetup
     mpEffectBox->insertItem(i18n("Colorize"));
     mpEffectBox->insertItem(i18n("Gamma"));
     mpEffectBox->insertItem(i18n("Desaturate"));
+    mpEffectBox->insertItem(i18n("To Monochrome"));
     mpEffectBox->setMinimumWidth( 100 );
     connect(mpEffectBox, SIGNAL(highlighted(int)), SLOT(slotEffectType(int)));
     top->addMultiCellWidget(mpEffectBox, 1, 2, 0, 0, Qt::AlignLeft);
@@ -566,6 +577,14 @@ KIconEffectSetupDialog::KIconEffectSetup
 		SLOT(slotEffectColor(const QColor &)));
     grid->addWidget(mpEColButton, 2, 1);
 
+    mpEffectColor2 = new QLabel(i18n("&Second color:"), mpEffectGroup);
+    grid->addWidget(mpEffectColor2, 3, 0);
+    mpECol2Button = new KColorButton(mpEffectGroup);
+    mpEffectColor->setBuddy( mpECol2Button );
+    connect(mpECol2Button, SIGNAL(changed(const QColor &)),
+		SLOT(slotEffectColor2(const QColor &)));
+    grid->addWidget(mpECol2Button, 3, 1);
+
     init();
     preview();
 }
@@ -579,9 +598,11 @@ void KIconEffectSetupDialog::init()
 {
     mpEffectBox->setCurrentItem(mEffect.type);
     mpEffectSlider->setEnabled(mEffect.type != KIconEffect::NoEffect);
-    mpEColButton->setEnabled(mEffect.type == KIconEffect::Colorize);
+    mpEColButton->setEnabled(mEffect.type == KIconEffect::Colorize || mEffect.type \
== KIconEffect::ToMonochrome); +    mpECol2Button->setEnabled(mEffect.type == \
KIconEffect::ToMonochrome);  mpEffectSlider->setValue((int) (100.0 * mEffect.value + \
0.5));  mpEColButton->setColor(mEffect.color);
+    mpECol2Button->setColor(mEffect.color2);
     mpSTCheck->setChecked(mEffect.transparant);
 }
 
@@ -597,13 +618,21 @@ void KIconEffectSetupDialog::slotEffectC
      preview();
 }
 
+void KIconEffectSetupDialog::slotEffectColor2(const QColor &col)
+{
+     mEffect.color2 = col;
+     preview();
+}
+
 void KIconEffectSetupDialog::slotEffectType(int type)
 {
     mEffect.type = type;
     mpEffectGroup->setEnabled(mEffect.type != KIconEffect::NoEffect);
     mpEffectSlider->setEnabled(mEffect.type != KIconEffect::NoEffect);
-    mpEffectColor->setEnabled(mEffect.type == KIconEffect::Colorize);
-    mpEColButton->setEnabled(mEffect.type == KIconEffect::Colorize);
+    mpEffectColor->setEnabled(mEffect.type == KIconEffect::Colorize || mEffect.type \
== KIconEffect::ToMonochrome); +    mpEColButton->setEnabled(mEffect.type == \
KIconEffect::Colorize || mEffect.type == KIconEffect::ToMonochrome); +    \
mpEffectColor2->setEnabled(mEffect.type == KIconEffect::ToMonochrome); +    \
mpECol2Button->setEnabled(mEffect.type == KIconEffect::ToMonochrome);  preview();
 }
 
@@ -625,7 +654,7 @@ void KIconEffectSetupDialog::preview()
     QPixmap pm;
     QImage img = mExample.copy();
     img = mpEffect->apply(img, mEffect.type,
-          mEffect.value, mEffect.color, mEffect.transparant);
+          mEffect.value, mEffect.color, mEffect.color2, mEffect.transparant);
     pm.convertFromImage(img);
     mpPreview->setPixmap(pm);
 }
Index: kcontrol/icons/icons.h
===================================================================
RCS file: /home/kde/kdebase/kcontrol/icons/icons.h,v
retrieving revision 1.13
diff -u -p -r1.13 icons.h
--- kcontrol/icons/icons.h	22 Oct 2004 19:11:15 -0000	1.13
+++ kcontrol/icons/icons.h	25 Nov 2004 13:18:55 -0000
@@ -44,6 +44,7 @@ struct Effect 
     int type;
     float value;
     QColor color;
+    QColor color2;
     bool transparant;
 };
 
@@ -128,6 +129,7 @@ protected:
 protected slots:
     void slotEffectValue(int value);
     void slotEffectColor(const QColor &col);
+    void slotEffectColor2(const QColor &col);
     void slotEffectType(int type);
     void slotSTCheck(bool b);
     void slotDefault();
@@ -138,11 +140,12 @@ private:
     QCheckBox *mpSTCheck;
     QSlider *mpEffectSlider;
     KColorButton *mpEColButton;
+    KColorButton *mpECol2Button;
     Effect mEffect;
     Effect mDefaultEffect;
     QImage mExample;
     QGroupBox *mpEffectGroup;
-    QLabel *mpPreview, *mpEffectLabel, *mpEffectColor;
+    QLabel *mpPreview, *mpEffectLabel, *mpEffectColor, *mpEffectColor2;
 };                      
                       
 #endif


["kdebase.diff" (text/x-diff)]

Index: kcontrol/icons/icons.cpp
===================================================================
RCS file: /home/kde/kdebase/kcontrol/icons/icons.cpp,v
retrieving revision 1.37
diff -u -p -r1.37 icons.cpp
--- kcontrol/icons/icons.cpp	22 Oct 2004 19:11:15 -0000	1.37
+++ kcontrol/icons/icons.cpp	21 Nov 2004 16:20:34 -0000
@@ -250,6 +250,8 @@ void KIconConfig::read()
 		effect = KIconEffect::ToGamma;
 	    else if (tmp == "desaturate")
 		effect = KIconEffect::DeSaturate;
+	    else if (tmp == "tomonochrome")
+		effect = KIconEffect::ToMonochrome;
 	    else if (tmp == "none")
 		effect = KIconEffect::NoEffect;
 	    else continue;
@@ -359,6 +361,9 @@ void KIconConfig::save()
 	    case KIconEffect::DeSaturate:
 		tmp = "desaturate";
 		break;
+	    case KIconEffect::ToMonochrome:
+		tmp = "tomonochrome";
+		break;
 	    default:
 		tmp = "none";
 		break;
@@ -526,6 +531,7 @@ KIconEffectSetupDialog::KIconEffectSetup
     mpEffectBox->insertItem(i18n("Colorize"));
     mpEffectBox->insertItem(i18n("Gamma"));
     mpEffectBox->insertItem(i18n("Desaturate"));
+    mpEffectBox->insertItem(i18n("To Monochrome"));
     mpEffectBox->setMinimumWidth( 100 );
     connect(mpEffectBox, SIGNAL(highlighted(int)), SLOT(slotEffectType(int)));
     top->addMultiCellWidget(mpEffectBox, 1, 2, 0, 0, Qt::AlignLeft);
@@ -579,7 +585,7 @@ void KIconEffectSetupDialog::init()
 {
     mpEffectBox->setCurrentItem(mEffect.type);
     mpEffectSlider->setEnabled(mEffect.type != KIconEffect::NoEffect);
-    mpEColButton->setEnabled(mEffect.type == KIconEffect::Colorize);
+    mpEColButton->setEnabled(mEffect.type == KIconEffect::Colorize || mEffect.type \
== KIconEffect::ToMonochrome);  mpEffectSlider->setValue((int) (100.0 * mEffect.value \
+ 0.5));  mpEColButton->setColor(mEffect.color);
     mpSTCheck->setChecked(mEffect.transparant);
@@ -602,8 +608,8 @@ void KIconEffectSetupDialog::slotEffectT
     mEffect.type = type;
     mpEffectGroup->setEnabled(mEffect.type != KIconEffect::NoEffect);
     mpEffectSlider->setEnabled(mEffect.type != KIconEffect::NoEffect);
-    mpEffectColor->setEnabled(mEffect.type == KIconEffect::Colorize);
-    mpEColButton->setEnabled(mEffect.type == KIconEffect::Colorize);
+    mpEffectColor->setEnabled(mEffect.type == KIconEffect::Colorize || mEffect.type \
== KIconEffect::ToMonochrome); +    mpEColButton->setEnabled(mEffect.type == \
KIconEffect::Colorize || mEffect.type == KIconEffect::ToMonochrome);  preview();
 }
 


["kdelibs2.diff" (text/x-diff)]

Index: kdecore/kiconeffect.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kiconeffect.cpp,v
retrieving revision 1.47
diff -u -p -r1.47 kiconeffect.cpp
--- kdecore/kiconeffect.cpp	7 Sep 2004 11:42:17 -0000	1.47
+++ kdecore/kiconeffect.cpp	25 Nov 2004 13:19:49 -0000
@@ -80,6 +80,7 @@ void KIconEffect::init()
     QString _desaturate("desaturate");
     QString _togamma("togamma");
     QString _none("none");
+    QString _tomonochrome("tomonochrome");
 
     KConfigGroupSaver cs(config, "default");
 
@@ -99,6 +100,9 @@ void KIconEffect::init()
         mColor[i][0] = QColor(144,128,248);
         mColor[i][1] = QColor(169,156,255);
         mColor[i][2] = QColor(34,202,0);
+        mColor2[i][0] = QColor(0,0,0);
+        mColor2[i][1] = QColor(0,0,0);
+        mColor2[i][2] = QColor(0,0,0);
 
 	config->setGroup(*it + "Icons");
 	for (it2=states.begin(), j=0; it2!=states.end(); it2++, j++)
@@ -112,6 +116,8 @@ void KIconEffect::init()
 		effect = DeSaturate;
 	    else if (tmp == _togamma)
 		effect = ToGamma;
+	    else if (tmp == _tomonochrome)
+		effect = ToMonochrome;
             else if (tmp == _none)
 		effect = NoEffect;
 	    else
@@ -120,6 +126,7 @@ void KIconEffect::init()
                 mEffect[i][j] = effect;
 	    mValue[i][j] = config->readDoubleNumEntry(*it2 + "Value");
 	    mColor[i][j] = config->readColorEntry(*it2 + "Color");
+	    mColor2[i][j] = config->readColorEntry(*it2 + "Color2");
 	    mTrans[i][j] = config->readBoolEntry(*it2 + "SemiTransparent");
 
 	}
@@ -150,11 +157,16 @@ QString KIconEffect::fingerprint(int gro
         cached += ':';
         cached += mTrans[group][state] ? QString::fromLatin1("trans")
             : QString::fromLatin1("notrans");
-        if (mEffect[group][state] == Colorize)
+        if (mEffect[group][state] == Colorize || mEffect[group][state] == \
ToMonochrome)  {
             cached += ':';
             cached += mColor[group][state].name();
         }
+        if (mEffect[group][state] == ToMonochrome)
+        {
+            cached += ':';
+            cached += mColor2[group][state].name();
+        }
     
         d->mKey[group][state] = cached;    
     }
@@ -175,11 +187,16 @@ QImage KIconEffect::apply(QImage image, 
 	return image;
     }
     return apply(image, mEffect[group][state], mValue[group][state],
-	    mColor[group][state], mTrans[group][state]);
+	    mColor[group][state], mColor2[group][state], mTrans[group][state]);
 }
 
 QImage KIconEffect::apply(QImage image, int effect, float value, const QColor col, \
bool trans) const  {
+    apply (image, effect, value, col, KGlobalSettings::baseColor(), trans);
+}
+
+QImage KIconEffect::apply(QImage image, int effect, float value, const QColor col, \
const QColor col2, bool trans) const +{
     if (effect >= LastEffect )
     {
 	kdDebug(265) << "Illegal icon effect: " << effect << "\n";
@@ -203,6 +220,9 @@ QImage KIconEffect::apply(QImage image, 
     case ToGamma:
         toGamma(image, value);
         break;
+    case ToMonochrome:
+        toMonochrome(image, col, col2, value);
+        break;
     }
     if (trans == true)
     {
@@ -224,12 +244,18 @@ QPixmap KIconEffect::apply(QPixmap pixma
 	return pixmap;
     }
     return apply(pixmap, mEffect[group][state], mValue[group][state],
-	    mColor[group][state], mTrans[group][state]);
+	    mColor[group][state], mColor2[group][state], mTrans[group][state]);
 }
 
 QPixmap KIconEffect::apply(QPixmap pixmap, int effect, float value,
 	const QColor col, bool trans) const
 {
+    apply (pixmap, effect, value, col, KGlobalSettings::baseColor(), trans);
+}
+
+QPixmap KIconEffect::apply(QPixmap pixmap, int effect, float value,
+	const QColor col, const QColor col2, bool trans) const
+{
     QPixmap result;
 
     if (effect >= LastEffect )
@@ -246,7 +272,7 @@ QPixmap KIconEffect::apply(QPixmap pixma
     else if ( effect != NoEffect )
     {
         QImage tmpImg = pixmap.convertToImage();
-        tmpImg = apply(tmpImg, effect, value, col, trans);
+        tmpImg = apply(tmpImg, effect, value, col, col2, trans);
         result.convertFromImage(tmpImg);
     }
     else
@@ -321,6 +347,40 @@ void KIconEffect::colorize(QImage &img, 
     }
 }
 
+void KIconEffect::toMonochrome(QImage &img, const QColor &black, const QColor \
&white, float value) { +   int pixels = (img.depth() > 8) ? img.width()*img.height() \
: img.numColors(); +   unsigned int *data = img.depth() > 8 ? (unsigned int *) \
img.bits() +         : (unsigned int *) img.colorTable();
+   int rval, gval, bval, alpha, i;
+   int rw = white.red(), gw = white.green(), bw = white.blue();
+   int rb = black.red(), gb = black.green(), bb = black.blue();
+   
+   double values = 0, sum = 0;
+   // Step 1: determine the average brightness
+   for (i=0; i<pixels; i++) {
+      sum += qGray(data[i])*qAlpha(data[i]) + 255*(255-qAlpha(data[i]));
+      values += 255;
+   }
+   double medium = sum/values;
+
+   // Step 2: Modify the image
+   for (i=0; i<pixels; i++) {
+      if (qGray(data[i]) <= medium) {
+         rval = static_cast<int>(value*rb+(1.0-value)*qRed(data[i]));
+         gval = static_cast<int>(value*gb+(1.0-value)*qGreen(data[i]));
+         bval = static_cast<int>(value*bb+(1.0-value)*qBlue(data[i]));
+      }
+      else {
+         rval = static_cast<int>(value*rw+(1.0-value)*qRed(data[i]));
+         gval = static_cast<int>(value*gw+(1.0-value)*qGreen(data[i]));
+         bval = static_cast<int>(value*bw+(1.0-value)*qBlue(data[i]));
+      }
+      
+      alpha = qAlpha(data[i]);
+      data[i] = qRgba(rval, gval, bval, alpha);
+   }
+}
+
 void KIconEffect::deSaturate(QImage &img, float value)
 {
     int pixels = (img.depth() > 8) ? img.width()*img.height()
Index: kdecore/kiconeffect.h
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kiconeffect.h,v
retrieving revision 1.25
diff -u -p -r1.25 kiconeffect.h
--- kdecore/kiconeffect.h	9 Sep 2004 15:23:51 -0000	1.25
+++ kdecore/kiconeffect.h	25 Nov 2004 13:19:49 -0000
@@ -52,8 +52,9 @@ public:
      * @li Colorize: Tints the icon with an other color
      * @li ToGamma: Change the gamma value of the icon
      * @li DeSaturate: Reduce the saturation of the icon
+     * @li ToMonochrome: Produces a monochrome icon
      */
-    enum Effects { NoEffect, ToGray, Colorize, ToGamma, DeSaturate, LastEffect };
+    enum Effects { NoEffect, ToGray, Colorize, ToGamma, DeSaturate, ToMonochrome, \
LastEffect };  
     /**
      * Rereads configuration.
@@ -102,6 +103,7 @@ public:
      */
     // KDE4: make them references
     QImage apply(QImage src, int effect, float value, const QColor rgb, bool trans) \
const; +    QImage apply(QImage src, int effect, float value, const QColor rgb, const \
QColor rgb2, bool trans) const;  
     /**
      * Applies an effect to a pixmap.
@@ -122,6 +124,7 @@ public:
      * @return A pixmap with the effect applied.
      */
     QPixmap apply(QPixmap src, int effect, float value, const QColor rgb, bool \
trans) const; +    QPixmap apply(QPixmap src, int effect, float value, const QColor \
rgb, const QColor rgb2, bool trans) const;  
     /**
      * Returns an image twice as large, consisting of 2x2 pixels.
@@ -162,6 +165,16 @@ public:
     static void colorize(QImage &image, const QColor &col, float value);
 
     /**
+     * Produces a monochrome icon with a given foreground and background color
+     *
+     * @param image The image
+     * @param white The color with which the white parts of @p image are painted
+     * @param black The color with which the black parts of @p image are painted
+     * @param value Strength of the effect. 0 <= @p value <= 1
+     */
+    static void toMonochrome(QImage &image, const QColor &black, const QColor \
&white, float value); +
+    /**
      * Desaturates an image.
      *
      * @param image The image
@@ -203,6 +216,7 @@ private:
     int mEffect[6][3];
     float mValue[6][3];
     QColor mColor[6][3];
+    QColor mColor2[6][3];
     bool mTrans[6][3];
     KIconEffectPrivate *d;
 };


["kdelibs.diff" (text/x-diff)]

? kdelibs.diff
Index: kdecore/kiconeffect.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kiconeffect.cpp,v
retrieving revision 1.47
diff -u -p -r1.47 kiconeffect.cpp
--- kdecore/kiconeffect.cpp	7 Sep 2004 11:42:17 -0000	1.47
+++ kdecore/kiconeffect.cpp	21 Nov 2004 16:21:03 -0000
@@ -80,6 +80,7 @@ void KIconEffect::init()
     QString _desaturate("desaturate");
     QString _togamma("togamma");
     QString _none("none");
+    QString _tomonochrome("tomonochrome");
 
     KConfigGroupSaver cs(config, "default");
 
@@ -112,6 +113,8 @@ void KIconEffect::init()
 		effect = DeSaturate;
 	    else if (tmp == _togamma)
 		effect = ToGamma;
+	    else if (tmp == _tomonochrome)
+		effect = ToMonochrome;
             else if (tmp == _none)
 		effect = NoEffect;
 	    else
@@ -150,7 +153,7 @@ QString KIconEffect::fingerprint(int gro
         cached += ':';
         cached += mTrans[group][state] ? QString::fromLatin1("trans")
             : QString::fromLatin1("notrans");
-        if (mEffect[group][state] == Colorize)
+        if (mEffect[group][state] == Colorize || mEffect[group][state] == ToMonochrome)
         {
             cached += ':';
             cached += mColor[group][state].name();
@@ -203,6 +206,9 @@ QImage KIconEffect::apply(QImage image, 
     case ToGamma:
         toGamma(image, value);
         break;
+    case ToMonochrome:
+        toMonochrome(image, col, KGlobalSettings::baseColor(), value);
+        break;
     }
     if (trans == true)
     {
@@ -321,6 +327,40 @@ void KIconEffect::colorize(QImage &img, 
     }
 }
 
+void KIconEffect::toMonochrome(QImage &img, const QColor &black, const QColor &white, float value) {
+   int pixels = (img.depth() > 8) ? img.width()*img.height() : img.numColors();
+   unsigned int *data = img.depth() > 8 ? (unsigned int *) img.bits()
+         : (unsigned int *) img.colorTable();
+   int rval, gval, bval, alpha, i;
+   int rw = white.red(), gw = white.green(), bw = white.blue();
+   int rb = black.red(), gb = black.green(), bb = black.blue();
+   
+   double values = 0, sum = 0;
+   // Step 1: determine the average brightness
+   for (i=0; i<pixels; i++) {
+      sum += qGray(data[i])*qAlpha(data[i]) + 255*(255-qAlpha(data[i]));
+      values += 255;
+   }
+   double medium = sum/values;
+
+   // Step 2: Modify the image
+   for (i=0; i<pixels; i++) {
+      if (qGray(data[i]) <= medium) {
+         rval = static_cast<int>(value*rb+(1.0-value)*qRed(data[i]));
+         gval = static_cast<int>(value*gb+(1.0-value)*qGreen(data[i]));
+         bval = static_cast<int>(value*bb+(1.0-value)*qBlue(data[i]));
+      }
+      else {
+         rval = static_cast<int>(value*rw+(1.0-value)*qRed(data[i]));
+         gval = static_cast<int>(value*gw+(1.0-value)*qGreen(data[i]));
+         bval = static_cast<int>(value*bw+(1.0-value)*qBlue(data[i]));
+      }
+      
+      alpha = qAlpha(data[i]);
+      data[i] = qRgba(rval, gval, bval, alpha);
+   }
+}
+
 void KIconEffect::deSaturate(QImage &img, float value)
 {
     int pixels = (img.depth() > 8) ? img.width()*img.height()
Index: kdecore/kiconeffect.h
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kiconeffect.h,v
retrieving revision 1.25
diff -u -p -r1.25 kiconeffect.h
--- kdecore/kiconeffect.h	9 Sep 2004 15:23:51 -0000	1.25
+++ kdecore/kiconeffect.h	21 Nov 2004 16:21:03 -0000
@@ -52,8 +52,9 @@ public:
      * @li Colorize: Tints the icon with an other color
      * @li ToGamma: Change the gamma value of the icon
      * @li DeSaturate: Reduce the saturation of the icon
+     * @li ToMonochrome: Produces a monochrome icon
      */
-    enum Effects { NoEffect, ToGray, Colorize, ToGamma, DeSaturate, LastEffect };
+    enum Effects { NoEffect, ToGray, Colorize, ToGamma, DeSaturate, ToMonochrome, LastEffect };
 
     /**
      * Rereads configuration.
@@ -162,6 +163,16 @@ public:
     static void colorize(QImage &image, const QColor &col, float value);
 
     /**
+     * Produces a monochrome icon with a given foreground and background color
+     *
+     * @param image The image
+     * @param white The color with which the white parts of @p image are painted
+     * @param black The color with which the black parts of @p image are painted
+     * @param value Strength of the effect. 0 <= @p value <= 1
+     */
+    static void toMonochrome(QImage &image, const QColor &black, const QColor &white, float value);
+
+    /**
      * Desaturates an image.
      *
      * @param image The image

[Attachment #11 (application/pgp-signature)]

_______________________________________________
kde-accessibility mailing list
kde-accessibility@kde.org
https://mail.kde.org/mailman/listinfo/kde-accessibility


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic