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:
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 );
18.191.150.231