Datatyping CategoriesOrganizing the data that we represent in a program can be a difficult task unless you have some sort of system that can be applied at a higher level to abstract the complex interactions that a machine must facilitate in order to make the data we interact with more accessible to us. Datatypes make the process of organizing the various forms of data that exist in our programs more accessible and categorically meaningful to us. What qualifies as a data type varies from one programming language to another and also forms the basis of what differentiates the two main programming paradigms we have been discussing, Procedural Programming and Object Oriented Programming. In Processing there are three main categories of data types that we will be dealing with Primitive datatypes, Processing's API datatypes and User Defined Complex datatypes.
Primitive datatypes form the building blocks of all the different types of data accessible within Processing. As a result these datatypes are immutable, meaning that we cannot modify their definitions by use of Processing.
intNumbers can be represented as Primitive datatypes and most commonly fall into the primitive datatype categories of int or float. An int data type is an abbreviation of the word integer and is used to create categories of numbers within a program that represent whole values such as 0, 1, -58, 6000000 and so on. In Processing an int can range in value anywhere between 2,147,483,647 to -2,147,483,648.
floatA float (or floating point number) is a data type used to categorize numbers that have a decimal point. Numbers such as 1.5, 3.0, -56.91 and even numbers such as 3.40282347E+38 in SI (the International System of Units) notation qualify to be a float primitive datatype.
charTypographic characters such as A, b, 5, @ etc can also be stored as primitive data types by use of the char datatype which is an abbreviation for the term character. However, storing a sequence of typographic characters as a single unit requires a different datatype that is more complex than a primitive.
Processing's API Datatypes
In order to make languages fit more specifically to an environment certain repetitive tasks are often automated by the developers of the language's API. The acronym API stands for Application Programming Interface and it refers to the means by which you communicate with a program. Although you are creating programs (known as sketches) with Processing, Processing in itself is also a software program. We have been communicating with Processing through the PDE, and within the PDE we have been typing statements instructing Processing what we would like it to do with the data we have supplied it with. Those instructions such as functions, tokens, arithmetic operators etc that we are using to communicate with Processing are all defined within Processing's API. Processing's API Datatypes are special datatypes defined within the Processing API that may or may not be found in other languages, but will make fulfilling the requirements of creating sketches (including data visualizations, end-user interactions and many other features commonly found in sketches) easier and less repetitive for the programmer by abstracting base-level computational interactions. The PImage datatype is an example of a Processing specific API Datatype that makes the task of using images within a sketch much simpler for the programmer. The String data type is a Processing non-specific API Datatype, meaning that although this datatype is common to many different programming languages it is not a primitive datatype as it uses characteristics of both int and char datatypes, this makes it more complex than a primitive datatype. Processing's API Datatypes are usually quite easy to identify as the keyword used to invoke them usually starts with an upper-case character, this is a common standardized programming practice that is used to identify Classes which are the fundamental building blocks of Object Oriented Programming and are an inherent quality of Processing's API design.
User Defined Complex Datatypes
In procedural based programming the programmer is supplied with a predetermined set of datatypes that can be used to communicate with other features of the programming language's API. As a result no matter what data the programmer is representing, that data must be tailored to suit those datatypes. This differs from an Object Oriented approach to programming, in that the programmer tailors the program to suit the data being represented. In other words with Object Oriented Programming the programmer creates custom definitions known as Classes by combining various primitive datatypes and predetermined complex datatypes of the programming language's API, with functions and directives to give the Class definition and meaning. These custom definitions (or Classes) are the basis from which datatypes that fall into the category of being User Defined Complex Datatypes originate. They are complex simply because they are often made up of more than one type of data. The most common of these datatypes is the Software Object or simply an Object, which is a copy or instance of a class. These datatypes can be used throughout a program in a manner that is akin to any other datatype. In other words to use a class in a program we must first create an instance of it, this instance is what we refer to as an object how the term Object Oriented Programming evolved.
The PImage Class defines useful information about the image we are loading into our sketch and allows us access to this information without having to understand how it has extracted this information from the image, such as it's width, height or how many pixels make up the image and what color each pixel is. This is one of the benefits of Object Oriented Programming, being able to abstract complex code by referencing it with a single keyword, the name of the object. We are going to create a new software object from the PImage class, and we will give this new object a name. It is important that the name that we assign to the new object is unique so that when ever we want to use that object we can refer to it by it's name and Processing will know exactly which object we are referring to. Amongst the prerequisites of using an image file as a background in Processing is that the image must be in either gif, jpg, png or tga format and must have the same dimensions as the sketch in which it will be displayed. If you have had a look at the smileBkg.png file you might have noticed that the dimensions do not match that of our current sketch. However, we are in luck because we have been using an implicit style of programming to specify the X and Y parameters within our sketch so changing the dimensions of our sketch at this late stage in the programming process is actually not going to be problematic. If, on the other hand, we had used an explicit style of programming we would have a problem as all of our had work to keep the graphical components of our sketch in the center of the display window and aligned with each other would now be lost and fixing it would mean having to go through every statement where X and Y coordinates where used and changing them to accommodate for the new sketch size. Since we are loading our image as a background we are going to add the following statements before the background statement near the top of the sketch. To create or as it is referred to in OOP-speak, instantiate a new object from the PImage class add the following statement before the background statement:
This statement tells Processing that we want to create a new software object which has all the properties of the PImage datatype and we would like to call this new object “img”. Our new software object has inherited the properties of the PImage class which allows us to access information about the image we would like to associate with the object named img (which we have instantiated from the PImage class), without having to know how it goes about accessing this information. However, what our new object does not know yet is what image we would like to use in our sketch and refer to as img, in other words what image do we want to associate with the img object? Add the following statement after the previous PImage statement in order to associate the image smileBkg.png with the img object:
This statement tells Processing the name and location of the image file we would like to use and refer to as img throughout the rest of our sketch. Because the image file has already been dropped into our sketch Processing has placed a copy of the file in our data folder. Processing will expect to find whatever image files we are using in our sketch in this folder. The loadImage() function can also accept a URL as a parameter if you wanted to load an image that is not located locally on the same station that your sketch is running from. Now that we have the image loaded into our sketch we need to tell Processing what we would like to do with and, where we want to place it and finally to draw the image to the Display Window. To display the image in our sketch we're going to modify the background statement and Processing will now render the image to the Display Window when we run the sketch. Modify the background statement to read:
img = loadImage("smileBkg.png");
This statement simply tells Processing that we would like to use the object named img as a background. Later we will have a look at compositing images on top of each other in addition to using them as backgrounds. To briefly recap on the steps we took to load an image into our sketch,
- 1. Drop the image into the PDE
- 2. Instantiate a new software object from the PImage Class
- 3. Load the image file into the new software object
- 4. Instruct Processing to display the image through it's identifier (name).