Transforming image contrast and brightness

In this recipe we will cover basic image color transformations using the Surface class for pixel manipulation.

Getting ready

To change the values of contrast and brightness we will use InterfaceGl covered in Chapter 2, Preparing for Development in the Setting up GUI for parameters tweaking recipe. We will need a sample image to proceed with; save it in your assets folder as image.png.

How to do it...

We will create an application with simple GUI for contrast and brightness manipulation on the sample image. Perform the following steps to do so:

  1. Include necessary headers:
    #include "cinder/gl/gl.h"
    #include "cinder/gl/Texture.h"
    #include "cinder/Surface.h"
    #include "cinder/ImageIo.h"
  2. Add properties to the main class:
    float mContrast,mContrastOld;
    float mBrightness,mBrightnessOld;
    Surface32f  mImage, mImageOutput;
  3. In the setup method an image is loaded for processing and the Surface object is prepared to store processed image:
    mImage = loadImage( loadAsset("image.png") );
    mImageOutput = Surface32f(mImage.getWidth(), 
            mImage.getHeight(), false);
  4. Set window size to default values:
    setWindowSize(1025, 512);
    mContrast = 0.f;
    mContrastOld = -1.f;
    mBrightness = 0.f;
    mBrightnessOld = -1.f;
  5. Add parameter controls to the InterfaceGl window:
    mParams.addParam("Contrast", &mContrast, 
    "min=-0.5 max=1.0 step=0.01");
    mParams.addParam("Brightness", &mBrightness, 
          "min=-0.5 max=0.5 step=0.01");
  6. Implement the update method as follows:
    if(mContrastOld != mContrast || mBrightnessOld != mBrightness) {
    float c = 1.f + mContrast;
        Surface32f::IterpixelIter = mImage.getIter();
        Surface32f::IterpixelOutIter = mImageOutput.getIter();
    
        while( pixelIter.line() ) {
        pixelOutIter.line();
        while( pixelIter.pixel() ) {
        pixelOutIter.pixel();
    
        // contrast transformation
        pixelOutIter.r() = (pixelIter.r() - 0.5f) * c + 0.5f;
        pixelOutIter.g() = (pixelIter.g() - 0.5f) * c + 0.5f;
        pixelOutIter.b() = (pixelIter.b() - 0.5f) * c + 0.5f;
    
        // brightness transformation
        pixelOutIter.r() += mBrightness;
        pixelOutIter.g() += mBrightness;
        pixelOutIter.b() += mBrightness;
    
            }
        }
    
    mContrastOld = mContrast;
    mBrightnessOld = mBrightness;
    }
  7. Lastly, we will draw the original and processed images by adding the following lines of code inside the draw method:
    gl::draw(mImage);
    gl::draw(mImageOutput, Vec2f(512.f+1.f, 0.f));

How it works...

The most important part is inside the update method. In step 6 we checked if the parameters for contrast and brightness had been changed. If they have, we iterate through all the pixels of the original image and store recalculated color values in mImageOutput. While modifying the brightness is just increasing or decreasing each color component, calculating contrast is a little more complicated. For each color component we are using the multiplying formula, color = (color - 0.5) * contrast + 0.5, where contrast is a number between 0.5 and 2. In the GUI we are setting a value between -0.5 and 1.0, which is more natural range; it is then recalculated at the beginning of step 6. While processing the image we have to change color value of all pixels, so later in step 6, you can see that we iterate through later columns of each row of the pixels using two while loops. To move to the next row we invoked the line method on the Surface iterator and then the pixel method to move to the next pixel of the current row. This method is much faster than using, for example, the getPixel and setPixel methods.

How it works...

Our application is rendering the original image on the left-hand side and the processed image on the right-hand side, so you can compare the results of color adjustment.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.157.6