# Increasing contrast of QImage

• Hello,

I develop GUI and algorithm for editing images , ideally it should work like Photoshop ( hhh ).
I've already made brightness control algorithm and UI and now I'm working on contrast increase/decrease of QImage,

next code ( part of a class method ) computes histogram of QImage ( imageToProcess and prev_image are class variables ), finds histogram center ( middle ) and tries to change image contrast by input value factor ( from 0 to 1 ) :

@
QMap<QRgb,long> histo; // histogram map
QMap<QRgb,long>::iterator j;
QRgb c = 0;
int l, k;
histo.clear();
for(k = 0; k < prev_image.width(); ++k)
for( l = 0; l < prev_image.height(); ++l) {
c = prev_image.pixel(k,l);

``````        if(!histo.contains(c))
histo.insert(c,0);
}
//computation of occurences
for( k = 0; k < prev_image.width(); ++k)
for( l = 0; l < prev_image.height(); ++l) {
c = prev_image.pixel(k,l);
histo[c] = histo[c]+1;
}
//compute average value
long sum_1 = 0;
long sum_2 = 0;
for(j = histo.begin();j!=histo.end();j++)
{
sum_1+=j.value()*j.key();
}
for(j = histo.begin();j!=histo.end();j++)
{
sum_2+=j.value();
}
long av = sum_1/sum_2;
av_r = qRed(av);
av_g = qGreen(av);
av_b = qBlue(av);
//changing contrast of an image by factor getted from horizontal slider ui:
double factor = (double)( (double)ie->horizontalSlider_2->value() )/100 ;    // to change also
if(factor!=0.99)
for (int y = 0; y < prev_image.height(); ++y) {
for (int x = 0; x < prev_image.width(); ++x) {
c = QRgb(prev_image.pixel(x,y));
QColor col(c);
col.getRgb(&r,&g,&b);
r = (int)(r*(1-factor)+av_r*factor);
g = (int)(g*(1-factor)+av_g*factor);
b = (int)(b*(1-factor)+av_b*factor);
if(r>255)
r=255;
if(g>255)
g=255;
if(b>255)
b=255;
imageToProcess->setPixel(x,y,qRgb(r,g,b));
}
}
if(factor!=0.99)
this->ie->label_11->setPixmap(QPixmap::fromImage(imageToProcess->scaled(this->ie->label_11->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation)));
else
this->ie->label_11->setPixmap(QPixmap::fromImage(prev_image.scaled(this->ie->label_11->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation)));@
``````

But actually what happens is that a contrast of an image changes ( only decreases in such a way ) and a background gets green when initial background is black or red when initial background is white.

How to increase contrast also ?

What to fix so that a background stays the same after contrast changing manipulations and does not get green/red ?

Sorry if the code is not formatted / eased to read.

• Well it's not really suprising as you in a certain point you multiply QRgb with long, assign the result to long and then tryto get color components of that. I don't if the algorithm is correct in general, but you absolutely should keep color channels independent.

• A small remark:
@
c = QRgb(prev_image.pixel(x,y));
QColor col(c);
col.getRgb(&r,&g,&b);
r = (int)(r*(1-factor)+av_rfactor);
g = (int)(g
(1-factor)+av_gfactor);
b = (int)(b
(1-factor)+av_b*factor);
@

why not simplify and don't use QColor:

@
c = prev_image.pixel(x,y);

``````       int r = (int)(c.red()*(1-factor)+av_r*factor);
int g = (int)(c.green()*(1-factor)+av_g*factor);
int b = (int)(c.blue()*(1-factor)+av_b*factor);
``````

@

Now the problem is really your algorithm:

# it's not possible to decompose your 'average' in RGB component values like you: because a grey could have after transformation any color: 128cst1 + av_rcst2 != 128cst1 + av_gcst2 -> no more grey.

• Hello, thanks for you answers.
I've came up with another algorithm like next :
@ if(factor!=1)
for (l = 0; l < working_image.height(); ++l) {
for (k = 0; k < working_image.width(); ++k) {
c = QRgb(working_image.pixel(k,l));
QColor col(c);
col.getRgb(&r,&g,&b);
double r_n = r / 255.0;
r_n -= 0.5;
r_n *= factor;
r_n += 0.5;
r_n *= 255;
double g_n = g / 255.0;
g_n -= 0.5;
g_n *= factor;
g_n += 0.5;
g_n *= 255;
double b_n = b / 255.0;
b_n -= 0.5;
b_n *= factor;
b_n += 0.5;
b_n *= 255;
if(r_n>255)
r_n=255;
if(r_n<0)
r_n=0;
if(g_n>255)
g_n=255;
if(g_n<0)
g_n=0;
if(b_n>255)
b=255;
if(b_n<0)
b_n=0;
imageToProcess->setPixel(k,l,qRgb((int)r_n,(int)g_n,(int)b_n));
}
}@

That works better but still far from perfect. I can't understand yet a better approach.

• Contrast in general is not a very simple thing, please check here