1
/* ============================================================
2
* Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
6
* Copyright 2004 by Renchi Raju
8
* This program is free software; you can redistribute it
9
* and/or modify it under the terms of the GNU General
10
* Public License as published by the Free Software Foundation;
11
* either version 2, or (at your option)
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* ============================================================ */
27
#define X_DISPLAY_MISSING 1
32
#include <qvbuttongroup.h>
33
#include <qradiobutton.h>
38
#include <kdialogbase.h>
40
#include <kapplication.h>
43
#include <kpassivepopup.h>
48
#include <imageiface.h>
52
#include "imageeffect_redeye.h"
54
class RedEyePassivePopup : public KPassivePopup
58
RedEyePassivePopup(QWidget* parent)
59
: KPassivePopup(parent), m_parent(parent)
65
virtual void positionSelf()
67
move(m_parent->x() + 30, m_parent->y() + 30);
75
void ImageEffect_RedEye::removeRedEye(QWidget* parent)
77
// -- check if we actually have a selection --------------------
79
Digikam::ImageIface iface(0, 0);
81
uint* data = iface.getSelectedData();
82
int w = iface.selectedWidth();
83
int h = iface.selectedHeight();
85
if (!data || !w || !h)
87
RedEyePassivePopup* popup = new RedEyePassivePopup(parent);
88
popup->setView(i18n("Red-Eye Correction Tool"),
89
i18n("You need to select a region including the eyes to use "
90
"the red-eye correction tool"));
91
popup->setAutoDelete(true);
92
popup->setTimeout(2500);
97
// -- run the dlg ----------------------------------------------
99
ImageEffect_RedEyeDlg dlg(parent);
101
if (dlg.exec() != QDialog::Accepted)
104
// -- save settings ----------------------------------------------
106
bool aggressive = (dlg.result() == ImageEffect_RedEyeDlg::Aggressive);
107
KConfig *config = kapp->config();
108
config->setGroup("ImageViewer Settings");
109
config->writeEntry("Red Eye Correction Plugin (Mild)",
113
// -- do the actual operations -----------------------------------
115
parent->setCursor( KCursor::waitCursor() );
117
uint* newData = new uint[w*h];
118
memcpy(newData, data, w*h*sizeof(unsigned int));
127
channel red_chan, green_chan, blue_chan;
129
red_chan.red_gain = 0.1;
130
red_chan.green_gain = 0.6;
131
red_chan.blue_gain = 0.3;
133
green_chan.red_gain = 0.0;
134
green_chan.green_gain = 1.0;
135
green_chan.blue_gain = 0.0;
137
blue_chan.red_gain = 0.0;
138
blue_chan.green_gain = 0.0;
139
blue_chan.blue_gain = 1.0;
141
float red_norm, green_norm, blue_norm;
143
red_norm = 1.0/(red_chan.red_gain + red_chan.green_gain + red_chan.blue_gain);
144
green_norm = 1.0/(green_chan.red_gain + green_chan.green_gain + green_chan.blue_gain);
145
blue_norm = 1.0/(blue_chan.red_gain + blue_chan.green_gain + blue_chan.blue_gain);
148
uint* nptr = newData;
152
for (int i=0; i<w*h; i++) {
154
a = (*ptr >> 24) & 0xff;
155
r = (*ptr >> 16) & 0xff;
156
g = (*ptr >> 8) & 0xff;
159
if ( aggressive || r >= ( 2 * g) )
161
r1 = (int) QMIN(255, red_norm * (red_chan.red_gain * r +
162
red_chan.green_gain * g +
163
red_chan.blue_gain * b));
164
b1 = (int) QMIN(255, green_norm * (green_chan.red_gain * r +
165
green_chan.green_gain * g +
166
green_chan.blue_gain * b));
167
g1 = (int) QMIN(255, blue_norm * (blue_chan.red_gain * r +
168
blue_chan.green_gain * g +
169
blue_chan.blue_gain * b));
171
*nptr = QMIN(int((r-g)/150.0*255.0),255) << 24 | r1 << 16 | g1 << 8 | b1;
178
Imlib_Context context = imlib_context_new();
179
imlib_context_push(context);
181
Imlib_Image imTop = imlib_create_image_using_copied_data(w, h, newData);
182
imlib_context_set_image(imTop);
183
imlib_image_set_has_alpha(1);
185
// blurring usually gives better results, but users might complain
186
// about loss of sharpness
187
//imlib_image_blur(1);
189
Imlib_Image imBot = imlib_create_image_using_copied_data(w, h, data);
190
imlib_context_set_image(imBot);
192
imlib_blend_image_onto_image(imTop, 0, 0, 0, w, h, 0, 0, w, h);
194
ptr = imlib_image_get_data_for_reading_only();
195
memcpy(data, ptr, w*h*sizeof(unsigned int));
197
imlib_context_set_image(imTop);
198
imlib_free_image_and_decache();
200
imlib_context_set_image(imBot);
201
imlib_free_image_and_decache();
204
imlib_context_free(context);
208
iface.putSelectedData(data);
211
parent->setCursor( KCursor::arrowCursor() );
214
ImageEffect_RedEyeDlg::ImageEffect_RedEyeDlg(QWidget* parent)
215
: KDialogBase(Plain, i18n("Red Eye Correction"),
216
Help|Ok|Cancel, Ok, parent, 0, true, true)
218
setHelp("redeyecorrectiontool.anchor", "digikam");
219
QVBoxLayout *topLayout = new QVBoxLayout( plainPage(),
222
QVButtonGroup* buttonGroup =
223
new QVButtonGroup( i18n("Level of Red-Eye Correction"),
225
buttonGroup->setRadioButtonExclusive( true );
227
QRadioButton* mildBtn =
228
new QRadioButton( i18n("Mild (use if other parts of the face are also selected)"),
230
QRadioButton* aggrBtn =
231
new QRadioButton( i18n("Aggressive (use if eye(s) have been selected exactly)" ),
234
topLayout->addWidget( buttonGroup );
236
connect( buttonGroup, SIGNAL(clicked(int)),
237
SLOT(slotClicked(int)) );
241
KConfig *config = kapp->config();
242
config->setGroup("ImageViewer Settings");
243
mild = config->readBoolEntry("Red Eye Correction Plugin (Mild)", true);
247
mildBtn->setChecked(true);
252
aggrBtn->setChecked(true);
257
ImageEffect_RedEyeDlg::Result ImageEffect_RedEyeDlg::result() const
259
return (Result)m_selectedId;
262
void ImageEffect_RedEyeDlg::slotClicked(int id)
267
#include "imageeffect_redeye.moc"