GIF Images on the Fly
The next example uses a few more of the functions supplied with the GD interface. We draw the arrow rather than read it from a file. By drawing the arrow, we can control the angle of the arrow which is drawn on the main image. Listing 2 shows the source code for this example.
Lines 1-8 should look familiar from the previous example. We simply define variables for the main GIF image and the position/angle of the arrow. Just for simplicity, I did not include the ReadParse routine, so no user input is allowed. As in the first example, we read the main image into the variable $im in Lines 10-12.
Line 15 is new. This line simply allocates a color based on RGB values which range from 0 to 255. The color blue has a RGB value of (0,0,255). We can then use the color later when drawing the arrow.
Lines 17 calls the function for creating the arrow. This routine starts on Line 26. In this routine we create a new polygon (an arrow) and then spend most of the time finding the points for the polygon. After we find an x,y position for a corner of the polygon, we put it in the polygon object, $poly.
As mentioned earlier, our polygon is an arrow. Line 37 creates the polygon variable. Then Lines 38-44 find points for the polygon. Here is how that section works. Lines 33-34 define the x,y positions for an arrow that points north. Since we may want to rotate this arrow, Lines 38-44 come into play. These lines figure out the new x,y positions of each point taking the rotation angle into consideration. Line 43 adds the point to the polygon taking into consideration the size of the image (subtracting 75) and the x,y position where the arrow will be placed ($xpos and $ypos). Rather than spending all day trying to explain this section of the code, take a look at an old CGA graphics book. In fact, I got the formulas for this section from a CGA graphics manual.
At last, we have a polygon stored as the variable $poly which is returned to the main program. Line 19 is another GD interface call to fill the arrow with our color and place it on the main image. Finally, the image is displayed and the script exits.
Like the first example, you can call this CGI script both directly and via an IMG tag as shown here:
<IMG SRC= "http://bodock.vislab.olemiss.edu/cgi-bin/example2.cgi" ALT="">
If you want to dynamically control the angle of the arrow, you would need to modify this example to include the cgi-lib.pl library, read in the data with ReadParse and then define $angle appropriately.
We now know how to create a GIF image on the fly and view it both directly and from an IMG tag within an HTML file. What if you need to save the image?
Of course, first of all you need a directory where the images will be created. Depending on your web-server configuration, the ownership and write permissions of that directory will need to be modified so that the CGI program can save the image. Discuss this matter with your webmaster.
Once that issue is resolved, your CGI script can output the image to a file using a unique, file-naming scheme. To recall this file name, you can use a database or simply inform the client of the name of the file. For example, if you develop a CGI program to create virtual postcards, the only person who needs the name of the image is the sender and/or the recipient of the postcard. This could be displayed within the web browser once the postcard has been created or e-mailed to the recipient. In other situations, several people may need to view the image. In this case, a database for storing the file name with the associated options is the best choice in my opinion.
In either case, storing the image can be done in addition to displaying it. That is, just use regular Perl I/O statements to print the image to a file. Pick up any Perl programming book and check out the File I/O section.
Last, you might have to keep a watch on the directory where the images are stored. If the file names are unique and the images are large, consider deleting old files periodically to avoid buying a new disk each month. Then again, you might want to use that as an excuse to obtain more disk space.
Of course, the documentation that comes with GD.pm can fill in any gaps that you might have. In addition, here are two URLs that show some of my programming work in creating GIF images on the fly. The first is a campus map for the University of Mississippi (UM). The second example highlights a few interesting sites about my home state.
For the UM campus map, the original GIF creation programs are written in C and use the gd C library. You can visit that page at the URL http://www.olemiss.edu/hospitality/maps/. The Find option at the top of the page will take you to other web pages. From there, you can select a site of interest. With a simple mouse click, an image is displayed of the campus with an arrow to highlight your selection. In addition, all the information on each building is listed in a database, so the CGI program has to first get this information before the image is created.
A more elaborate example of GIF images created on the fly can be found at the URL http://bodock.vislab.olemiss.edu/onthefly.html. This combines several options such as text, a choice of colors, a variety of pointers, etc. Be sure to follow the “More Practical Example” link at the bottom of the left-most frame. That section shows examples of adding several text and highlighters at the same time. In addition, the map is clickable thanks to some HTML code for a a client-side image map. The CGI programs for this application were developed with Perl and the other packages mentioned earlier.
|Designing Electronics with Linux||May 22, 2013|
|Dynamic DNS—an Object Lesson in Problem Solving||May 21, 2013|
|Using Salt Stack and Vagrant for Drupal Development||May 20, 2013|
|Making Linux and Android Get Along (It's Not as Hard as It Sounds)||May 16, 2013|
|Drupal Is a Framework: Why Everyone Needs to Understand This||May 15, 2013|
|Home, My Backup Data Center||May 13, 2013|
- RSS Feeds
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- A Topic for Discussion - Open Source Feature-Richness?
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Validate an E-Mail Address with PHP, the Right Way
- What's the tweeting protocol?
- Tech Tip: Really Simple HTTP Server with Python
- Kernel Problem
1 hour 13 min ago
- BASH script to log IPs on public web server
5 hours 40 min ago
9 hours 16 min ago
- Reply to comment | Linux Journal
9 hours 48 min ago
- All the articles you talked
12 hours 12 min ago
- All the articles you talked
12 hours 15 min ago
- All the articles you talked
12 hours 17 min ago
16 hours 41 min ago
- Keeping track of IP address
18 hours 32 min ago
- Roll your own dynamic dns
23 hours 46 min ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi
It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?