Processing Tutorial -- Showing Animated Gifs

From dftwiki
Jump to: navigation, search

--D. Thiebaut (talk) 20:18, 11 October 2017 (EDT)





0: Youtube Tutorial


If you prefer to follow the tutorial on video, I have created a short YouTube tutorial. It covers the material presented in this page.


1: Create the Sketch


By creating the sketch first, and saving it, this will create a folder where all the files associated with the sketch will reside. This project requires many files, including images for the background of the aquarium and for the fish.
Create a simple sketch with an empty draw() and setup() function and save it under an easy name to remember. We'll assume here that the name of the sketch is "aquarium".
Once the sketch is saved, locate the aquarium folder just created, and create a new folder inside it called data. The data folder is the place where sketches keep the different images that are used in the graphics.

2: Find an Aquarium Image


Search the Web for an image of an aquarium that you like. Pick one that is around 1000 pixels wide, and at least 600 pixels high. For this Lab, we will use the following aquarium image, named aquarium.jpg.

ProcessingAquarlum.jpg


When you have found your image, save it in the data folder you created in your sketch folder.


3: Find an Animated Fish


Search the Web for an animated gif file of a fish with a transparent background. Animated gifs are images that are animated when displayed in a browser. Animated gif files contain several images (frames) that are shown in a loop, one after the other, and look "animated." Gif with transparent backgrounds can be shown on top of other images, and their rectangular shape doesn't show: just the figure in the middle shows when put on top of another image. Look at the image at the very top of this page: it shows a fish in the aquarium. Actually the fish is an animated gif (not animated here, since it was captured), but its rectangular frame doesn't show. Google shows transparent background with a checkered background, as shown below (URL):

AnimatedGifFishTransparent.png



Google should be able to show you the fish moving, as shown below:

AnimagedFish.gif



Save the fish in the data folder of your sketch folder. We'll call this image fish.gif in this tutorial.

4: Put the Fish and Aquarium Together


We won't see the fish move yet, but we want to see how they both look together.
Change the code in your sketch to read as follows:

PImage img;
PImage fish;

void setup() {
  size( 1000, 600 );
  smooth();
  img = loadImage( "aquarium.jpg" );
  fish = loadImage( "fish.gif" );
}

void draw() {
  image( img, 0, 0, width, height );
  image( fish, 100, 100 );
}


This is what we get with the aquarium and fish files we have picked. Yours should look similar, more or less. The fish won't move. That's normal. We have to do some work to make Processing animate the fish. In particular we will need to extract the different frames from the fish and make individual images out of each one.

FixedFishOnAquarium.png



5: Break Up the Fish into Frames


In order to show the fish moving in our sketch, we need to extract the different frames that comprise the animated fish gif, make them individual images, store them in the sketch folder, and display them one after the other over the aquarium.
If you have a Mac, you can use the Preview app to extract the frames from a gif. Open the animated gif in Preview. Each of the frames appear in the tab on the left. To extract each frame, just select it, type Command+C to copy it, then Command+N to paste it in as a new file. Number your files in the same order the frames appear in the gif: 0, 1, 2, etc.
If you do not have a Mac, there are many different sites on the Web that will take a gif file and extract the different frames from it. ezgif.com is one of them. Click on this link and upload your animated fish gif to it. Then split it!
You should get a window like this, showing the animated gif you uploaded, and below, all the frames it contains.

GoogleFishSplitter.png



In this case we have 8 frames extracted from the gif, and we need to save them as individual images in the data folder. Go ahead and control-click on each frame, and save it with a numbered name, such as fish0.gif, fish1.gif, ... fish7.gif.

6: Animated (Frantic) Fish in Aquarium


We are now ready to modify our sketch and have it use our new fish gifs.

// aquarium
// https://ezgif.com/split/ezgif-4-2831abd0f3.gif
// 
PImage img;
PImage[] fish = new PImage[8];

void setup() {
  size( 1000, 600 );
  smooth();
  img = loadImage( "aquarium.jpg" );
  fish[0] = loadImage( "fish0.gif" );
  fish[1] = loadImage( "fish1.gif" );
  fish[2] = loadImage( "fish2.gif" );
  fish[3] = loadImage( "fish3.gif" );
  fish[4] = loadImage( "fish4.gif" );
  fish[5] = loadImage( "fish5.gif" );
  fish[6] = loadImage( "fish6.gif" );
  fish[7] = loadImage( "fish7.gif" );
}

void draw() {
  image( img, 0, 0, width, height );
  image( fish[frameCount%8], 200, 200 );
}


We have created an array of fish images. This way we can easily display one image of this array every time draw() is called. The draw() function is called 30 times a second, normally. So we will display approximately 30 frames of the fish every second. Processing maintains a special counter called frameCount that is incremented every time the draw() function is called. If we use frameCount % 8 (frameCount modulo 8), we get numbers that go 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, ... ad infinitum. This is exactly what we need to pick each of our 8 frames, one after the other.
Try your sketch. Verify that your fish moves, possibly faster than the original gif.

7: Slowing Down the Fish


If our fish is too fast at moving, we can reduce the number of frames per second, or the number of times the function draw() is called. Simply add a call to a new function called frameRate() at the end of setup():

    frameRate( 10 );


This will reduce the number of times draw() is called to 10 times a second. Adjust this number so that your fish moves at a "normal" pace.

8: Making the fish swim from left to right


Our fish is moving, but doesn't go anywhere. Let's make it go places!
For that we need to remember where it is, i.e. its x and y position in the window, and then slowing change the x value and redraw it at the new place. We need to global variables, which we'll call fishX and fishY as follows:

// aquarium
// https://ezgif.com/split/ezgif-4-2831abd0f3.gif
// 
PImage img;
PImage[] fish = new PImage[8];
int fishX = -100, fishY = height/2;

void setup() {
  size( 1000, 600 );
  smooth();
  img = loadImage( "aquarium.jpg" );
  fish[0] = loadImage( "fish0.gif" );
  fish[1] = loadImage( "fish1.gif" );
  fish[2] = loadImage( "fish2.gif" );
  fish[3] = loadImage( "fish3.gif" );
  fish[4] = loadImage( "fish4.gif" );
  fish[5] = loadImage( "fish5.gif" );
  fish[6] = loadImage( "fish6.gif" );
  fish[7] = loadImage( "fish7.gif" );
  frameRate( 10 );
}

void draw() {
  image( img, 0, 0, width, height );
  image( fish[frameCount%8], fishX, fishY );
  fishX = fishX + 5;
  if ( fishX > width+100)  {
      fishX = -250;
  }
}



9: Enhancements


Hope you enjoyed this tutorial. If you wanted to explore this further, and learn some more Processing (and Java), here are some ideas.

  1. A good next step would be to create a class for the fish, so that all the frames and its position would be stored inside fish objects. This way you could create a school of several fish very easily. (Actually, since I first wrote this part, I couldn't resist implementing an object-oriented variation of this aquarium. You can find the solution with a school of object-fish here).
  1. You might also want to use different animated gifs for creating different fish.
  1. Find images of rocks or corals that have a transparent background, and display them last inside the draw() function. This way the fish will swim "on top" of the aquarium image, but "behind" the coral image. Cool effect.
  1. You may want to have the fish make bubbles randomly. The bubble can just be circles with a white line that slowly move up once they are generated outside the mouth of the fish.
  1. You could also generate a bubble fountain starting at the bottom of the aquarium with a new bubble created every time draw() is called, and slowly climbing up to the top. The bubbles could grow in size as they climb up...
  1. Have fun!



10: Files


Here are the files used for this project. For each image, click on it first to see the full size version of it. Then download it to your computer and store it in the data folder in your sketch folder.

Tank

ProcessingAquarlum.jpg

Frame 0

AnimatedFishFrame0.gif

Frame 1

AnimatedFishFrame1.gif

Frame 2

AnimatedFishFrame2.gif

Frame 3

AnimatedFishFrame3.gif

Frame 4

AnimatedFishFrame4.gif

Frame 5

AnimatedFishFrame5.gif

Frame 6

AnimatedFishFrame6.gif

Frame 7

AnimatedFishFrame7.gif