|
Chapter: Visual
Representations
of Code
Finishing the Sketch
Datatyping Categories
Organizing 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
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.
int
Numbers 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.
float
A 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.
char
Typographic 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.
Chapter: Visual
Representations
of Code
PImage
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:
PImage img;
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:
img = loadImage("smileBkg.png");
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:
background(img);
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).
The completed
“Hello World 1.2” Program
|
|