Using threshold

Now we are going to use some per-pixel manipulation. We will choose one certain threshold value between 0 and 255 and compare each channel of each pixel to that value. If the value is above the threshold, we will change the channel value to maximum (255). If the value is less, we will change it to the minimum (0).

Note

Previously we were using floating point numbers from 0 to 1 to describe R, G, and B channels. When using Surface objects and images in general, you might want to know that each pixel of each channel of the Surface (Surface8u) object consists of 8 bits that can hold 256 values from 0 to 255 if not defined otherwise.

As we are dealing with a still image, we have to do this process only once, in the setup() method between the surface and texture object initialization. We will make use of a really handy helper class, Surface::Iter, that will allow us to loop seamlessly through lines (rows) and individual pixels of each line.

So this is the code that we have to add to the setup() method implementation between the surface and texture variable initialization lines as follows:

surface = Surface( loadImage( loadAsset("OurImage.png") ) );

int threshold = 200;
Area area = surface.getBounds();
Surface::Iter iter = surface.getIter( area );
while( iter.line() ) {
  while( iter.pixel() ) {
    iter.r() = iter.r() > threshold ? 255 : 0;
    iter.g() = iter.g() > threshold ? 255 : 0;
    iter.b() = iter.b() > threshold ? 255 : 0;
  }
}

texture = gl::Texture( surface );

First we define the threshold, all the values above that will be changed to 255 and all the values below or equal will be changed to 0. Say goodbye to smooth gradients. Next we get the area of the image that we will change. To change the whole image, we have to get the bounds of the whole surface. We have to get an iterator (iter) to construct a nice nested loop afterwards. Finally we use the iterator to loop through all the lines (rows) and pixels (columns inside the row) of the surface and change it's pixels one by one.

Don't forget to change the Texture initialization (you have to use our Surface instance again instead of Channel):

texture = gl::Texture( surface );

Note that we initialize the texture after we make changes to the pixels of the surface. Every time you make changes to the Surface object that you will be using as a Texture afterwards, you have to reinitialize the texture variable from the changed Surface object.

Compile and run the project, and see what happens! The following screenshot shows the comparison between the source image and the one with our threshold filter applied:

Using threshold

Try to experiment a bit by changing the threshold value and the way pixel values are being changed before we move on to the next part.

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

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