Chapter 7. Working with Images – Real-time Postprocessing and Effects

In this chapter we will talk about basic approaches of using built-in Cinder classes for applying effects to still and moving images.

In this chapter we will learn the following:

  • Understanding the difference between CPU and GPU image processing
  • Applying basic effects to images
  • Looping through pixels of an image as well as a movie frame
  • Making use of the pixel-level access

Introducing Texture, Surface, and Channel

In Chapter 5, Making Use of Images – Loading and Displaying, we already learned how to load an image into Cinder. The following is the essence of the code we used there:

gl::Texture texture = loadImage( loadAsset( "image.jpg" ) );

With this line of code we load pixels from the image.jpg image file into the GPU memory. Texture is meant for storing the image data but not for manipulating or displaying it. To show the image on the screen, we use the following line of code:

gl::draw( texture );

Say we want to do some image processing in between the load and draw stages. To process images on the GPU (where the image data is stored by the Texture objects), we would use shaders. Shaders make use of the OpenGL Shading Language and we won't go in detail about this now as it is way outside the scope of this book.

There is another way of processing the image, that is by loading the image on the CPU. To make use of the CPU, we have to use the Surface class. It is similar to the Texture class but the main difference is that it stores the image data on the CPU. By loading an image on the CPU, we can do the image processing with the C++ code.

To draw a surface, we will need to convert it to a Texture instance. It is possible to convert the Surface data to the Texture class instances for drawing something similar to the following:

Surface surface;
gl::Texture texture = gl::Texture( surface );

By performing the preceding code, we create a GPU friendly texture for displaying it on the screen.

There is a third image datatype in Cinder, the Channel class. If the Surface class is able to hold red, green, blue, and alpha values in separate channels within one object, then Channel makes use of just one channel (can hold one of the channels mentioned) and can be used to store grayscale images.

It is possible to create a Surface instance from a Channel class by adding the following line:

Surface surface( channel );

The preceding line of code makes it is possible to create a high-quality, grayscale image as a Channel class instance by passing a Surface instance to the Channel directly.

Channel channel( surface );
..................Content has been hidden....................

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