381 lines
32 KiB
HTML
381 lines
32 KiB
HTML
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>How to generate images with JpGraph library</title><link rel="stylesheet" type="text/css" href="manual.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.0"><link rel="home" href="index.html" title="JpGraph Manual"><link rel="up" href="ch05.html" title="Chapter 5. Fundamentals of dynamic graph generation"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">How to generate images with JpGraph library</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center">Chapter 5. Fundamentals of dynamic graph generation</th><td width="20%" align="right"> </td></tr></table><hr></div><div class="sect1" title="How to generate images with JpGraph library"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2494304"></a>How to generate images with JpGraph library</h2></div></div></div>
|
||
|
||
<p>The two common steps for creating and using a Graph on your Web-page are</p>
|
||
<p>
|
||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
<p>Create a script that constructs the graph, by getting the data and
|
||
specifying how the graph should look, the size, what colors to use, what
|
||
fonts to use and specifying other augmentations on the graph.</p>
|
||
</li><li class="listitem">
|
||
<p>On the HTML page where the graph(s) should be displayed include add
|
||
one or more <span class="markup"><img></span> tags which links to the PHP graphs
|
||
script. Of course it is perfectly possible to call the image script
|
||
directly in the browser to just display the generated image in the
|
||
browser. This way it is possible to include any number of graphs on the
|
||
Web-page.</p>
|
||
</li></ol></div><p>
|
||
</p>
|
||
<div class="tip" title="Tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3>
|
||
<p>One further thing to keep in mind is that it is also possible to pass
|
||
arguments to the image script via the normal HTTP GET/POST arguments. </p>
|
||
<p>For example </p>
|
||
<p>
|
||
</p><pre class="screen"><img src="showgraph.php?a=1&b=2"> </pre><p>
|
||
</p>
|
||
<p>This could be used to control the appearance of the image or perhaps send data
|
||
to the image which will be displayed. Note that this is probably not the best
|
||
way to send large amount of data to plot. Instead the only practical way, for
|
||
large data sizes, is to get all the data in the image script directly, perhaps
|
||
from a DB. Another alternative for large amount of data to be sent to the image
|
||
script is by creating a POST request to the image script. This is further
|
||
discussed in ?? (Getting hold of the data to be displayed)</p>
|
||
</div>
|
||
<div class="sect2" title="The standard steps of setting up a graph"><div class="titlepage"><div><div><h3 class="title"><a name="id2494467"></a>The standard steps of setting up a graph</h3></div></div></div>
|
||
|
||
<p>When it comes to the structure of your imaging script they will generally have
|
||
the following structure </p>
|
||
<p>
|
||
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ... Include necessary headers </span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">jpgraph.php</span><span class="hl-quotes">'</span><span class="hl-code">;
|
||
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">....</span><span class="hl-quotes">'</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Create the graph instance</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Graph</span><span class="hl-brackets">(</span><span class="hl-var">$width</span><span class="hl-code">,</span><span class="hl-var">$height</span><span class="hl-code">, ...</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Specify what scale should be used in the graph</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">...</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ... code to construct the graph details and plot objects</span><span class="hl-comment"></span><span class="hl-code">
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Add one or many plot objects to the graph</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Add</span><span class="hl-brackets">(</span><span class="hl-code">..</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ... and send back the graph to the client</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
||
</p>
|
||
<p>JpGraph is completely Object oriented so all calls will be action on specific
|
||
instances of classes. One of the fundamental classes is the <code class="code">Graph()</code>
|
||
class which represents the entire graph.</p>
|
||
<p>After the creation of the <code class="code">Graph()</code> object all the code lines to
|
||
construct the details of the graph are added. The final method called in an
|
||
image script will most likely be the <code class="code">Graph::Stroke()</code> method. This
|
||
will send the constructed image back to the browser. A variation of this is used
|
||
if the graph are supposed to have image maps (CSIM). In that case the final
|
||
method will be <code class="code">Graph::StrokeCSIM()</code></p>
|
||
<p>
|
||
</p><div class="caution" title="Caution" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Caution</h3>
|
||
<p>As discussed in <a class="xref" href="ch05.html#sec1.making-sense-of-HTTP-streams" title="Making sense of HTTP streams and MIME types">Making sense of HTTP streams and MIME types</a> no text can be
|
||
returned from an image script. Beware!</p>
|
||
</div><p>
|
||
</p>
|
||
<p>In addition to this standard usage pattern you can also choose to:</p>
|
||
<p>
|
||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
<p>... send the graph directly to a file. This is done by specifying
|
||
a filename as parameter to the final <code class="code">Stroke()</code> method
|
||
call. See <a class="xref" href="ch05s05.html#sec2.writing-miage-to-file" title="Writing the image directly to a file">Writing the image directly to a file</a> for more detailed
|
||
information.</p>
|
||
</li><li class="listitem">
|
||
<p>... access the GD image handler for further image processing (also
|
||
needed to include the image in an PDF file, see <a class="xref" href="apc.html" title="Appendix C. FAQ">Appendix C. <i>FAQ</i></a>)</p>
|
||
</li><li class="listitem">
|
||
<p>... make use of the built-in cache system to send back a
|
||
previously generated image. The cache system, which lessens the
|
||
burden of the PHP server, works by avoiding running all the code
|
||
that follows the initial <code class="code">Graph()</code> call by checking if
|
||
the image has already been created and in that case directly send
|
||
back the previously created (and stored in a file) image file to the
|
||
browser. The filename used for the image can be either manually
|
||
selected or automatically created based on the script name. In
|
||
addition it is also possible to specify a timeout value in the
|
||
initial call to the Graph() constructor to indicate how long the
|
||
image in the cache directory should be considered valid before a new
|
||
image is generated. A full description of the JpGraph cache system
|
||
is available in <a class="xref" href="ch05s06.html" title="Efficient graph generation using the built-in cache subsystem">Efficient graph generation using the built-in cache subsystem</a>.</p>
|
||
<p>
|
||
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3>
|
||
<p>The cache system by default is disabled and must be
|
||
enabled by setting the proper define in the file
|
||
"j<code class="filename">pg-config.inc</code>"</p>
|
||
</div><p>
|
||
</p>
|
||
</li><li class="listitem">
|
||
<p>... combine several graphs in the same image using the
|
||
<code class="code">MGraph()</code> class (Multi-Graph). This is an advanced
|
||
technique described in ??.</p>
|
||
</li></ol></div><p>
|
||
</p>
|
||
</div>
|
||
<div class="sect2" title="Choosing the image compression format for JpGraph"><div class="titlepage"><div><div><h3 class="title"><a name="id2494641"></a>Choosing the image compression format for JpGraph</h3></div></div></div>
|
||
|
||
<p>By default JpGraph automatically chooses the image format to use in the order
|
||
PNG, JPEG and GIF. The exact format depends on what is available on the system
|
||
the library is installed on. There are two ways you can influence the way the
|
||
graphic format is chosen:</p>
|
||
<p>
|
||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
<p>Change the default graphic format by changing the DEFINE (in
|
||
<code class="filename">jpg-config.inc.php</code>)</p>
|
||
<p><code class="code">DEFINE('DEFAULT_GFORMAT','auto')</code></p>
|
||
<p>For example; if you by default want all your images to be
|
||
generated with JPG encodation the define should be changed to </p>
|
||
<p><code class="code">DEFINE('DEFAULT_GFORMAT','jpg')</code></p>
|
||
</li><li class="listitem">
|
||
<p>By dynamically (in your script) select the wanted compression
|
||
format with a call to</p>
|
||
<p><code class="code">Image::SetImgFormat()</code></p>
|
||
<p>For example; if you want your image to use the JPEG format </p>
|
||
<p>
|
||
<code class="code">$graph->img->SetImgFormat('jpeg')</code></p>
|
||
<p> (The above line assume that you have called your variable that
|
||
holds the instantiated <code class="code">Graph()</code> object
|
||
"<code class="code">$graph</code>"</p>
|
||
</li></ol></div><p>
|
||
</p>
|
||
</div>
|
||
<div class="sect2" title="Sending back the image to the browser"><div class="titlepage"><div><div><h3 class="title"><a name="id2494706"></a>Sending back the image to the browser</h3></div></div></div>
|
||
|
||
<p>The very last statement in almost all graph scripts is the line</p>
|
||
<p>
|
||
</p><pre class="screen">$graph->Stroke();</pre><p>
|
||
</p>
|
||
<p>
|
||
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3>
|
||
<p>Actually there are some valid exceptions to this when you do some more
|
||
advanced graph generation involving caching together with the CSIM
|
||
functionality.</p>
|
||
</div><p>
|
||
</p>
|
||
<p>This line starts the actual graph creation. All method calls up to this stage
|
||
has just been to set the scene for the library and specify all necessary
|
||
parameters. It is first when you make the call to the <code class="code">Stroke()</code>
|
||
method the library actually starts to build the image. Assuming there are no
|
||
errors detected when the image is generated the library will now take the
|
||
following steps in principle:</p>
|
||
<p>
|
||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
<p>Start building the image in memory. This is done by analyzing the
|
||
specified parameters and making use of the supplied data in order to
|
||
create the various plots that have been specified.</p>
|
||
</li><li class="listitem">
|
||
<p>Check what headers are needed, i.e. what image compression are
|
||
used for the graph, and send that header back to the client.</p>
|
||
<p>The library also have to check how the library was called since if
|
||
it was called from the command line no MIME headers should be sent
|
||
back at all, just the raw image data. Running the command line
|
||
version of PHP will allow you to dynamically create images without
|
||
using a HTTP server.</p>
|
||
</li><li class="listitem">
|
||
<p>Send the actual image data representing the built up image back to
|
||
the client</p>
|
||
</li></ol></div><p>
|
||
</p>
|
||
<div class="warning" title="The dreaded: Headers has already been sent error" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">The dreaded: Headers has already been sent error</h3>
|
||
|
||
<p>This is an error that everyone, and we really mean everyone, will see one
|
||
time or the other when producing dynamic images with PHP.</p>
|
||
<p>First, this is not a problem with JpGraph per se. What has happened is
|
||
that your PHP script which produces the image has already returned some data
|
||
to the client before the image header has been sent. </p>
|
||
<p>This is most often caused by one or more spaces before the first
|
||
"<code class="code"><?php</code>" statement. What happens is that the server
|
||
normally sends back all data it finds in the files it reads. Since the
|
||
server no sees a space, a perfectly valid character, it will send that data
|
||
back to the client. However, before it does that it will automatically
|
||
generate a header. Since it has seen a normal character data it will
|
||
generate a header telling the client to expect a data stream of
|
||
characters.</p>
|
||
<p>When later JpGraph tries to send its image header the server will detect
|
||
that a header has already been sent and since each HTTP data stream can only
|
||
have one type (and hence only one header) it will generate an error message
|
||
which is sent back to the client.</p>
|
||
<p>To correct this error check your files for any output (even a single
|
||
space) before the call to <code class="code">Graph::Graph()</code> (or
|
||
<code class="code">Graph::Stroke()</code>) If you are running on older version of a
|
||
Windows server this problem could also be caused by blank line at the end of
|
||
the files. On some older Windows versions together with PHP4 it might also
|
||
be called by a file ending in a newline (which all the JpGraph library files
|
||
does) Remove the newline so that the file ends just after the final
|
||
"<code class="code">?></code>" Also remember that when you include external file
|
||
using <code class="code">include/include_once</code> and so on PHP includes the whole
|
||
content of the file; this content of the file also includes any potential
|
||
carriage return/line feed or "blank" space before "<code class="code"><?php</code>"
|
||
and after "<code class="code">?>"</code> These "dirty characters" will cause the problem
|
||
just described. </p>
|
||
</div>
|
||
</div>
|
||
<div class="sect2" title="Writing the image directly to a file"><div class="titlepage"><div><div><h3 class="title"><a name="sec2.writing-miage-to-file"></a>Writing the image directly to a file</h3></div></div></div>
|
||
|
||
<p>In addition to just streaming the file back to the browser it is also possible
|
||
to write the file directly to a named file. The file name is given as an
|
||
argument to the Graph::Stroke() method. For example as </p>
|
||
<p><code class="code">$graph->Stroke('/tmp/myimage.png');</code></p>
|
||
<p>There are three important things to note here</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
<p>The PHP process must have write permission on the directory you
|
||
are trying to write the image file on. If you are running PHP
|
||
through your browser this means that the HTTP server process must
|
||
have write permission on that directory.</p>
|
||
</li><li class="listitem">
|
||
<p>The file suffix (e.g. '<code class="code">.png</code>') should match the image
|
||
compression type used.</p>
|
||
</li><li class="listitem">
|
||
<p>If the image is streamed directly to a file and not back to the
|
||
browser the script can of course return ordinary text.</p>
|
||
</li></ol></div>
|
||
<div class="tip" title="Writing the image to both a file and stream it back to the browser" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Writing the image to both a file and stream it back to the
|
||
browser</h3>
|
||
|
||
<p>In this case you should instead use the method
|
||
<code class="code">Graph::StrokeStore($aFileName)</code> which was introduced in
|
||
version 2.5 of the library. If you are on a previous version and for various
|
||
reasons cannot upgrade then you can use the following "trick" to achieve
|
||
this.</p>
|
||
<p>The idea is to use the <code class="code">_IMG_HANDLER</code> option that forces the
|
||
<code class="code">Graph::Stroke()</code> to just return the image handler and then
|
||
stop. We can then manually first send the image to the chosen file and then
|
||
stream it back to the browser using some internal methods in the library.
|
||
The following code snippet shows how this is done.
|
||
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ... necessary includes ...</span><span class="hl-comment"></span><span class="hl-code">
|
||
|
||
</span><span class="hl-var">$graph</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Graph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">300</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ... code to generate a graph ...</span><span class="hl-comment"></span><span class="hl-code">
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Get the handler to prevent the library from sending the</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> image to the browser</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$gdImgHandler</span><span class="hl-code"> = </span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-identifier">_IMG_HANDLER</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Stroke image to a file and browser</span><span class="hl-comment"></span><span class="hl-code">
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Default is PNG so use ".png" as suffix</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$fileName</span><span class="hl-code"> = </span><span class="hl-quotes">"</span><span class="hl-string">/tmp/imagefile.png</span><span class="hl-quotes">"</span><span class="hl-code">;
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">Stream</span><span class="hl-brackets">(</span><span class="hl-var">$fileName</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Send it back to browser</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">Headers</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">Stream</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div>
|
||
</div>
|
||
</div>
|
||
<div class="sect2" title="Alternatives to streaming or storing the image"><div class="titlepage"><div><div><h3 class="title"><a name="id2494959"></a>Alternatives to streaming or storing the image</h3></div></div></div>
|
||
|
||
<p>There are also two predefined filenames which have special meaning when
|
||
supplied as argument ot the <code class="code">Stoke()</code> method.</p>
|
||
<p>
|
||
</p><div class="variablelist"><dl><dt><span class="term"><code class="code">_IMG_AUTO</code></span></dt><dd>
|
||
<p>This will create a file in the same directory as the script
|
||
with the same name as the script but with the correct image
|
||
extension. </p>
|
||
</dd><dt><span class="term"><code class="code">_IMG_HANDLER</code></span></dt><dd>
|
||
<p>Specifying this filename will not create a an image to file
|
||
nor stream it back to the browser. Instead it will instruct the
|
||
<code class="code">Stroke()</code> method to just return the handle for
|
||
the GD image. This is useful if you later want to manipulate the
|
||
image in ways that are not yet supported by JpGraph. For example
|
||
include the image in a dynamically generated PDF file. See <a class="xref" href="apc.html" title="Appendix C. FAQ">Appendix C. <i>FAQ</i></a> for a detailed example how to
|
||
include an image in a PDF generated with the "fpdf"
|
||
library.</p>
|
||
</dd></dl></div><p>
|
||
</p>
|
||
</div>
|
||
<div class="sect2" title="Forcing the browser to update your graph"><div class="titlepage"><div><div><h3 class="title"><a name="sec2.forcing-browser-update"></a>Forcing the browser to update your graph</h3></div></div></div>
|
||
|
||
<p>Some browser may not send back a request to the HTTP server unless the user
|
||
presses "Refresh" (F5 - in most browsers). This can lead to problems that the
|
||
user is seeing old data since the file stamp of the script might not change but
|
||
the data the script is using to create the image/graph is. A simple trick is to
|
||
add a dummy time argument which is not used in the script. </p>
|
||
<p>For example </p>
|
||
<p><code class="code"><img src="myimagescript.php?dummy=\'.now()."></code>
|
||
</p>
|
||
<p>Since the dummy argument will be a new number whenever the browser checks it
|
||
the browser understands that it must re-fetch the script and force the image to
|
||
be reloaded and redisplayed.</p>
|
||
<p>It is also important to be aware of any internal caching the browser might do.
|
||
The general problem with dynamically generated images is that the image
|
||
generating script (file) remains the same. This makes the browser believe that
|
||
the data hasn\'t changed (since the script is the same) and if the browser
|
||
already has issued a previous GET request and has the data cached it will not
|
||
send a new GET if the time stamp on the file is the same since it then believes
|
||
it should and can use the old browser cached version.</p>
|
||
</div>
|
||
<div class="sect2" title="Printing the generated image"><div class="titlepage"><div><div><h3 class="title"><a name="id2495089"></a>Printing the generated image</h3></div></div></div>
|
||
|
||
<p>Some browsers, most notable IE (< v7) can have issues printing a dynamic
|
||
image. This is because the designers of IE assumed that all images are
|
||
traditional images that are available as static image files. Not that they could
|
||
be dynamically generated. This unfortunately have some implications.</p>
|
||
<p>
|
||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
<p>IE will often (always?) re-fetch the page when preparing to print.
|
||
This means that a new image will be generated and is perhaps very
|
||
different from what the user thinks he is printing (if the data is
|
||
changing rapidly).</p>
|
||
</li><li class="listitem">
|
||
<p>Some older versions of IE simply refuses to print dynamic images
|
||
if they are not available as a static "*.png", "*.jpg" etc. file.
|
||
The only known workaround is to make sure to use static
|
||
images.</p>
|
||
</li></ol></div><p>
|
||
</p>
|
||
<p>There is one final reported problem to be aware of. Normally most browsers
|
||
will support "right-clicking" on an image to download the image locally.
|
||
However, some older versions of IE will become very confused when dynamic images
|
||
are used. This could manifest itself as that the file type is not the wanted,
|
||
for example, trying to download a "*.png" image could cause the file to be saved
|
||
as a "*.bmp" file instead. </p>
|
||
<p>Newer versions of IE seems to be able to handle dynamic images much
|
||
better.</p>
|
||
<p>It should also be mentioned that some older versions of FireFox (< v3)
|
||
could in some circumstances fetch a dynamic image twice causing unnecessary load
|
||
on the server (See <code class="uri"><a class="uri" href="https://bugzilla.mozilla.org/show_bug.cgi?id=331126" target="_top">FireFox
|
||
Bugzilla</a></code>). However, there are no known issues with dynamic images in
|
||
current versions of FireFox and IE (i.e. IE v8).</p>
|
||
</div>
|
||
</div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"><a accesskey="u" href="ch05.html">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
|