📄 ch32.htm
字号:
<HTML>
<HEAD>
<TITLE>Chapter 32 -- Dynamic Image Creation</TITLE>
<META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 32</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Dynamic Image Creation</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>
<UL>
<LI><A HREF="#Introduction" >Introduction</A>
<LI><A HREF="#TwoDimensionalPlots" >Two-Dimensional Plots</A>
<LI><A HREF="#ThreeDimensionalPlots" >Three-Dimensional Plots</A>
<LI><A HREF="#UsingtheOutputinCGIApplications" >Using the Output in CGI Applications</A>
<LI><A HREF="#CreatingGIFImagesDirectlyfromPerl" >Creating GIF Images Directly from Perl</A>
<UL>
<LI><A HREF="#InstallingthegdLibrary" >Installing the gd Library</A>
<LI><A HREF="#InstallingGDpm" >Installing GD.pm</A>
</UL>
<LI><A HREF="#WorkingwithGDpm" >Working with GD.pm</A>
<LI><A HREF="#UsingGDwithHTMLPages" >Using GD with HTML Pages</A>
<LI><A HREF="#Summary" >Summary</A>
</UL>
<HR>
<P>
This chapter covers how to create GIF images from within a Perl
program. The output of the programs developed here can be used
in HTML pages or for other graphical applications. If you have
not already done so, please read <A HREF="ch20.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch20.htm" >Chapter 20</A>,
"An Introduction to Web Pages and CGI," for some of
the background you'll need for this chapter.
<H2><A NAME="Introduction"><B><FONT SIZE=5 COLOR=#FF0000>Introduction</FONT></B></A>
</H2>
<P>
When writing Perl applications, it's often necessary to display
the results of your application graphically. One common way to
display these results is to print them in columns and pipe the
output to a display program such as <TT><FONT FACE="Courier">gnuplot</FONT></TT>.
<P>
For most applications, <TT><FONT FACE="Courier">gnuplot</FONT></TT>
works great for plotting charts or columnar data. By using <TT><FONT FACE="Courier">gnuplot</FONT></TT>,
you can print many types of charts, using different types of axes,
colors, and so on. It's possible to write a script for <TT><FONT FACE="Courier">gnuplot</FONT></TT>
to extract data from columns from within a data file. I won't
go into too much detail here. The purpose of this chapter is to
show you how to use Perl to control <TT><FONT FACE="Courier">gnuplot</FONT></TT>,
not how to program <TT><FONT FACE="Courier">gnuplot</FONT></TT>.
Type <TT><B><FONT FACE="Courier">help</FONT></B></TT> at the <TT><FONT FACE="Courier">gnuplot</FONT></TT>
prompt to get an interactive manual that contains details on how
to program in <TT><FONT FACE="Courier">gnuplot</FONT></TT>.
<P>
Though this scheme of using <TT><FONT FACE="Courier">gnuplot</FONT></TT>
works well for most applications, it does have a few drawbacks:
<UL>
<LI><FONT COLOR=#000000>There are two processes involved in the
image creation. The use of system resources for such image creation
is high for complex images. Even if you do not use an intermediate
file to store the points for display, you still have to use a
pipe to send the output to the rasterization program.</FONT>
<LI><TT><FONT FACE="Courier">Gnuplot</FONT></TT> allows non-interactive
operation through the use of scripts. Some rasterization programs
do not work in this manner. In this case, some intermediate format
has to be chosen to create the images.
<LI><FONT COLOR=#000000>The entire process of generating an image
involves creating the points for the image in a palatable format
for the rasterization program to pick. This puts the onus on the
program for massaging data into an array, if necessary, before
printing it out. Doing this makes the code harder to program but
saves you from the grunt work of managing the details of the image
yourself. It's generally easier to create the image all in one
go.</FONT>
<LI><FONT COLOR=#000000>For Web applications, using a GIF image
format for the output makes it easier to load into Web pages.
</FONT><TT><FONT FACE="Courier">Gnuplot</FONT></TT> can generate
images in many formats but does not produce images in the GIF
format.
</UL>
<P>
To extract a GIF image from a plot generated by a plotting program
such as <TT><FONT FACE="Courier">gnuplot</FONT></TT>, you can
use yet another utility, the Portable BitMap (<TT><FONT FACE="Courier">pbmutils</FONT></TT>)
package. The <TT><FONT FACE="Courier">pbmutils</FONT></TT> package
is a general-purpose image format conversion tool available from
many Ftp sites as the <TT><FONT FACE="Courier">netpbm.tar.gz</FONT></TT>
file.
<P>
Before I go too far in generating images, let's use a tool to
view the output of the images that we'll be creating. For this
chapter, we'll be using the <TT><FONT FACE="Courier">xv</FONT></TT>
(version 3.1) tool set by John Bradley. The <TT><FONT FACE="Courier">xv</FONT></TT>
tool is remarkably practical for interactively viewing images
in many formats. It also performs resizing, cropping, and color
palette modifications for images. The tool is available from <TT><FONT FACE="Courier">sunsite.unc.edu</FONT></TT>
and various other sites. Search for <I>xv</I>. The 3.1 version
was copyrighted by John Bradley in 1994. The <TT><FONT FACE="Courier">xv</FONT></TT>
tool proved to be invaluable in debugging the output of the programs
in this chapter. You can use any image-viewing tool you like,
depending on your platform.
<P>
Now that we have the means to create and display images, let's
see how to perform image plotting with Perl and <TT><FONT FACE="Courier">gnuplot</FONT></TT>.
<H2><A NAME="TwoDimensionalPlots"><B><FONT SIZE=5 COLOR=#FF0000>Two-Dimensional
Plots</FONT></B></A></H2>
<P>
First, here's a simple example of how to plot two-dimensional
data with <TT><FONT FACE="Courier">gnuplot</FONT></TT>. For the
data, we'll use the file with columnar data, part of which is
shown in Listing 32.1.
<HR>
<BLOCKQUOTE>
<B>Listing 32.1. Input data file.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">930830 32.375 31.750 32.000 3700.0 118.4000
<BR>
930831 32.250 31.625 32.125 3962.2 127.2857<BR>
930902 31.750 31.375 31.500 3721.8 117.2367<BR>
930903 31.500 31.125 31.375 3447.6 108.1685<BR>
930907 32.000 30.750 31.000 4425.0 137.1750<BR>
930908 31.625 30.125 31.500 10847.8 341.7057<BR>
930909 32.750 31.250 32.375 10338.6 334.7122<BR>
930910 33.375 32.500 32.750 9323.2 305.3348<BR>
930913 33.000 32.375 32.375 3809.2 123.3229<BR>
930915 32.500 31.375 32.438 11356.8 368.3862</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
What we'll do is plot the difference between the items in column
1 and column 2 for all the samples. The data file is a history
of stock prices, and we want to look at the fluctuation of prices
in a per-day basis. Listing 32.2 contains the Perl script used
to extract the data from the display file and to display the data
using <TT><FONT FACE="Courier">gnuplot</FONT></TT>.
<HR>
<BLOCKQUOTE>
<B>Listing 32.2. Using Perl to generate 2D plots.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2<BR>
3<BR>
4 open( PLOTFILE, ">data1") || die "\n
Cannot open plot file $! \n";<BR>
5 open( DATAFILE, "INTC") || die "\n Cannot
open $! \n";<BR>
6<BR>
7 $i = 0;<BR>
8 while (<DATAFILE>) {<BR>
9 ($date,$hi,$lo,$cl,$vol,$other)
= split(' ',$_);<BR>
10 printf PLOTFILE "%6.1f %6.1f\n",
$i, $hi-$lo;<BR>
11 $i++;<BR>
12 }<BR>
13 close PLOTFILE;<BR>
14 close DATAFILE;<BR>
15<BR>
16 open (GNUPLOT,"| gnuplot");<BR>
17<BR>
18 print GNUPLOT <<gnuplot_commands;<BR>
19 set term pbm color small<BR>
20 set output "myoutput.pbm"
<BR>
21 set title "Test 1"<BR>
22 plot "data1"<BR>
23 gnuplot_commands<BR>
24<BR>
25<BR>
26 close GNUPLOT;<BR>
27<BR>
28 `ppmtogif myoutput.pbm > myoutput.gif 2>/dev/null
`;<BR>
29 # The next line is used to view the output file<BR>
30 `xv myoutput.gif`;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The input data file is organized as one record per line. Each
record contains the date, followed by the high, low, and closing
prices of the day and the volume. In line 9 of the listing, we
extract the high and low prices of the day and in line 10 we print
out the maximum fluctuation of these prices along with an index
value.
<P>
<A HREF="f32-1.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/f32-1.gif" ><B>Figure 32.1 : </B><I>Using 2D plots.</I></A>
<P>
This listing does four things: From lines 4 to 14 we are extracting
the data from the input file, <TT><FONT FACE="Courier">INTC</FONT></TT>,
and creating a temporary disk file called <TT><FONT FACE="Courier">data1</FONT></TT>.
Then lines 18 through 26 render the image in PBM format. Line
28 uses the PBM utilities to convert from PBM to GIF. All functions
for the PBM utilities as well as the <TT><FONT FACE="Courier">xv</FONT></TT>
program must be located somewhere in the directories listed in
the <TT><FONT FACE="Courier">PATH</FONT></TT> environment variable.
Line 30 uses the <TT><FONT FACE="Courier">xv</FONT></TT> tools
to view the image just created. Line 30 is really not required,
but is included only as a debug line.
<P>
Look at lines 4 and 5, where the output and input files are opened.
Each line from the input file is extracted in line 9. The calculated
output is written to the output file in line 10. A value for the
horizontal axis is created for the output by auto-incrementing
the <TT><FONT FACE="Courier">$i</FONT></TT> variable. After the
input file is completely read, both the input and output files
are closed in lines 13 and 14.
<P>
At line 16, we open the <TT><FONT FACE="Courier">GNUPLOT</FONT></TT>
handle to send all output to <TT><FONT FACE="Courier">gnuplot</FONT></TT>.
You must have the program <TT><FONT FACE="Courier">gnuplot</FONT></TT>
located somewhere in the directories listed in the <TT><FONT FACE="Courier">PATH</FONT></TT>
environment variable. For line 16 to work, <TT><FONT FACE="Courier">gnuplot</FONT></TT>
must exist in a directory defined by the <TT><FONT FACE="Courier">PATH</FONT></TT>
or reside in the current directory. The following commands are
sent to the <TT><FONT FACE="Courier">gnuplot</FONT></TT> program
from lines 19 up to line 22. Line 23 terminates the input to the
<TT><FONT FACE="Courier">gnuplot</FONT></TT> program:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">19 set term
pbm color small<BR>
20 set output "myoutput.pbm"
<BR>
21 set title "Test 1"<BR>
22 plot "data1"</FONT></TT>
</BLOCKQUOTE>
<P>
Here's how the commands to <TT><FONT FACE="Courier">gnuplot</FONT></TT>
work. The terminal type is set to PBM output in color using small
fonts. The output file is set to <TT><FONT FACE="Courier">myoutput.pbm</FONT></TT>
instead of the terminal. The title of the plot is set to Test
1. The plot command is used to render the image with the data
in the file <TT><FONT FACE="Courier">data1</FONT></TT>.
<P>
Finally, at line 27, we take all data from the PBM file we just
created and convert it to a GIF file using the <TT><FONT FACE="Courier">`ppmtogif`</FONT></TT>
utility. The command shown in line 28 also redirects the standard
error handle, <TT><FONT FACE="Courier">stderr</FONT></TT>, which
is <TT><FONT FACE="Courier">2</FONT></TT>, to redirect its output
to <TT><FONT FACE="Courier">/dev/null</FONT></TT>.
<P>
Line 30 is used to call the <TT><FONT FACE="Courier">xv</FONT></TT>
program to view what we have just created. The call to <TT><FONT FACE="Courier">xv</FONT></TT>
is not required, and in fact should be made only if you have already
successfully installed <TT><FONT FACE="Courier">xv</FONT></TT>
or to call whatever image-viewing software you happen to be using.
<P>
The process to generate the data plot is quite straightforward.
Simply write the data to a temp file, open a pipe to <TT><FONT FACE="Courier">gnuplot</FONT></TT>,
and then write commands directly to <TT><FONT FACE="Courier">gnuplot</FONT></TT>
to render the data. The output from <TT><FONT FACE="Courier">gnuplot</FONT></TT>
may have to go to a different rendering or image-converting utility
to get the format you want.
<H2><A NAME="ThreeDimensionalPlots"><B><FONT SIZE=5 COLOR=#FF0000>Three-Dimensional
Plots</FONT></B></A></H2>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -