<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IONCANNON &#187; php</title>
	<atom:link href="http://www.ioncannon.net/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ioncannon.net</link>
	<description>Thoughts on Software Development and Engineering</description>
	<lastBuildDate>Tue, 03 Jan 2012 13:59:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
	<atom:link rel='hub' href='http://www.ioncannon.net/?pushpress=hub'/>
		<item>
		<title>Java GIF Adventure</title>
		<link>http://www.ioncannon.net/php/79/java-gif-adventure/</link>
		<comments>http://www.ioncannon.net/php/79/java-gif-adventure/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 14:14:29 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/php/79/java-gif-adventure/</guid>
		<description><![CDATA[I was recently working on a project that generated PNGs using Java from a Java2D canvas. Along the way someone wanted to change the graphics to have transparent backgrounds and because they were needed for display on the web I knew this would become an issue because IE doesn&#039;t support transparency in PNGs out of [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently working on a project that generated PNGs using Java from a Java2D canvas. Along the way someone wanted to change the graphics to have transparent backgrounds and because they were needed for display on the web I knew this would become an issue because <a href="http://blogs.msdn.com/dmassy/archive/2004/08/05/209428.aspx">IE doesn&#039;t support transparency in PNGs</a> out of the box. And so my journey started.</p>
<p><span id="more-79"></span></p>
<p>I decided to start by making the PNGs I was generating transparent just to verify that it wasn&#039;t that difficult to do. It turned out to be very easy. I&#039;m using the standard ImageIO libraries and wanted to stick to using them. Here is an example of making the background of an image transparent:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="kw1">public</span> <span class="kw1">class</span> Test<br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">public</span> <span class="kw1">static</span> <span class="kw4">void</span> main<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a><span class="br0">&#91;</span><span class="br0">&#93;</span> args<span class="br0">&#41;</span> <span class="kw1">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Exception</span></a><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a> image <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a><span class="br0">&#40;</span>100, 100, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a>.<span class="me1">TYPE_INT_ARGB</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Agraphics2d+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Graphics2D</span></a> canvas <span class="sy0">=</span> <span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Agraphics2d+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Graphics2D</span></a><span class="br0">&#41;</span> image.<span class="me1">getGraphics</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; canvas.<span class="me1">setRenderingHint</span><span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Arenderinghints+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">RenderingHints</span></a>.<span class="me1">KEY_ANTIALIASING</span>, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Arenderinghints+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">RenderingHints</span></a>.<span class="me1">VALUE_ANTIALIAS_ON</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; canvas.<span class="me1">setColor</span><span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Acolor+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Color</span></a>.<span class="me1">white</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; canvas.<span class="me1">setBackground</span><span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Acolor+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Color</span></a>.<span class="me1">white</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; canvas.<span class="me1">setComposite</span><span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aalphacomposite+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">AlphaComposite</span></a>.<span class="me1">getInstance</span><span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aalphacomposite+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">AlphaComposite</span></a>.<span class="me1">SRC_OVER</span>, 0.0f<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; canvas.<span class="me1">fillRect</span><span class="br0">&#40;</span>0, 0, 100, 100<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; canvas.<span class="me1">setComposite</span><span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aalphacomposite+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">AlphaComposite</span></a>.<span class="me1">getInstance</span><span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aalphacomposite+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">AlphaComposite</span></a>.<span class="me1">SRC_OVER</span>, 1.0f<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; canvas.<span class="me1">setColor</span><span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Acolor+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Color</span></a>.<span class="me1">black</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; canvas.<span class="me1">drawLine</span><span class="br0">&#40;</span>10, 10, 20, 20<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; canvas.<span class="me1">dispose</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aoutputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">OutputStream</span></a> ostream <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Afileoutputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">FileOutputStream</span></a><span class="br0">&#40;</span><span class="st0">&quot;test.png&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; ImageIO.<span class="me1">write</span><span class="br0">&#40;</span>image, <span class="st0">&quot;png&quot;</span>, ostream<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; ostream.<span class="me1">flush</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>The next thing I did was try to just change the format that was being saved from &#034;png&#034; to &#034;gif&#034; thinking that because I had a recent version of Java 1.5 this might just work. However it appears that <a href="http://forum.java.sun.com/thread.jspa?threadID=770668&#038;messageID=4391702">writting GIFs is not supported until Java 1.6</a> so I was out of luck.</p>
<p>As it turns out though I did some more searching and found that there is actually a <a href="https://gif-plugin.dev.java.net/">plugin for GIFs</a> that was made for the ImageIO system. It was very easy to install, just download the jar and put it into the classpath. After that changing &#034;png&#034; to &#034;gif&#034; worked. However, the plugin doesn&#039;t support alpha or doesn&#039;t support it in the same way as the PNG writer. I then tried to change the transparency around a number of ways but nothing worked and in some cases the GIF generated was broken. The most promising hack I tried was to change the alpha flag on the background color using a BufferedImageOp filter like this:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimageop+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImageOp</span></a> filter <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimageop+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImageOp</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a> filter<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a> src, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a> dest<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>dest <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dest <span class="sy0">=</span> createCompatibleDestImage<span class="br0">&#40;</span>src, <span class="kw2">null</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> width <span class="sy0">=</span> src.<span class="me1">getWidth</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> height <span class="sy0">=</span> src.<span class="me1">getHeight</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> y <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> y <span class="sy0">&lt;</span> height<span class="sy0">;</span> y<span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> x <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> x <span class="sy0">&lt;</span> width<span class="sy0">;</span> x<span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> src.<span class="me1">getRGB</span><span class="br0">&#40;</span>x, y<span class="br0">&#41;</span> <span class="sy0">==</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Acolor+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Color</span></a>.<span class="me1">white</span>.<span class="me1">getRGB</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dest.<span class="me1">setRGB</span><span class="br0">&#40;</span>x, y, 0x00FFFFFF <span class="sy0">&amp;</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Acolor+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Color</span></a>.<span class="me1">white</span>.<span class="me1">getRGB</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> dest<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Arectangle2d+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Rectangle2D</span></a> getBounds2D<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a> src<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> src.<span class="me1">getRaster</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">getBounds</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a> createCompatibleDestImage<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a> src, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Acolormodel+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">ColorModel</span></a> destCM<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>destCM <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; destCM <span class="sy0">=</span> src.<span class="me1">getColorModel</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> width <span class="sy0">=</span> src.<span class="me1">getWidth</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> height <span class="sy0">=</span> src.<span class="me1">getHeight</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Abufferedimage+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">BufferedImage</span></a><span class="br0">&#40;</span>destCM, destCM.<span class="me1">createCompatibleWritableRaster</span><span class="br0">&#40;</span>width, height<span class="br0">&#41;</span>, destCM.<span class="me1">isAlphaPremultiplied</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, <span class="kw2">null</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Apoint2d+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Point2D</span></a> getPoint2D<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Apoint2d+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Point2D</span></a> srcPt, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Apoint2d+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Point2D</span></a> dstPt<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>dstPt <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dstPt <span class="sy0">=</span> <span class="kw1">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Apoint2d+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Point2D</span></a>.<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Afloat+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">Float</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; dstPt.<span class="me1">setLocation</span><span class="br0">&#40;</span>srcPt.<span class="me1">getX</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, srcPt.<span class="me1">getY</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> dstPt<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; <span class="kw1">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Arenderinghints+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">RenderingHints</span></a> getRenderingHints<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">null</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy0">;</span></div>
</div>
<p>The problem with this approach is that the anti-aliasing caused the borders to stand out. While this was close it also wasn&#039;t good enough to use.</p>
<p>In the end I gave up and went back to PNGs. I fixed my issues with IE by using the <a href="http://www.twinhelix.com/css/iepngfix/">IE AlphaImageLoader fix</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/php/79/java-gif-adventure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Akismet spam graphs with PHP RRD</title>
		<link>http://www.ioncannon.net/php/113/akismet-spam-graphs-with-php-rrd/</link>
		<comments>http://www.ioncannon.net/php/113/akismet-spam-graphs-with-php-rrd/#comments</comments>
		<pubDate>Mon, 01 Jan 2007 17:37:33 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[utilities]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/php/113/akismet-spam-graphs-with-php-rrd/</guid>
		<description><![CDATA[After reading a post on hacking Akismet to add graphs I decided I liked the idea but I didn&#039;t want to store the data in a database. It seemed like it would be better to store it using a RRD and then use the PHP RRD library. So after a little hacking I&#039;ve created a [...]]]></description>
			<content:encoded><![CDATA[<p>After reading a post on <a href="http://blog.joshuaeichorn.com/archives/2006/12/21/more-spam-fun/">hacking Akismet to add graphs</a> I decided I liked the idea but I didn&#039;t want to store the data in a database. It seemed like it would be better to store it using a RRD and then use the PHP RRD library. So after a little hacking I&#039;ve created a version that does basically the same thing except uses a RRD.</p>
<p><span id="more-113"></span></p>
<p>A good place to start is the <a href="http://www.ioncannon.net/system-administration/59/php-rrdtool-tutorial/">PHP RRDTool tutorial</a>. It will make it easier to read the following code if you have an idea of how to use the RRDTool extension.</p>
<p>All of the following changes should be made in the plugins/akismet directory.</p>
<p>The first part of the code is akismet_rrd.php that adds a utility function for updating the RRD file. It will create the file if it doesn&#039;t already exist. To gather the stats on incoming spam it uses a timestamp of the last time it ran and then queries WordPress&#039;s comment table for anything marked as spam in increments that match the step used to set up the RRD. The update function can be called in a number of locations but the most efficient seems to be right before any deletes happen.</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span><br />
<a href="http://www.php.net/define"><span class="kw3">define</span></a><span class="br0">&#40;</span><span class="st_h">&#039;AKISMET_RRD_FILE&#039;</span><span class="sy0">,</span> ABSPATH <span class="sy0">.</span> <span class="st_h">&#039;wp-content/plugins/&#039;</span> <span class="sy0">.</span> <a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span>plugin_basename<span class="br0">&#40;</span><span class="kw4">__FILE__</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">&#039;/akismet.rrd&#039;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/define"><span class="kw3">define</span></a><span class="br0">&#40;</span><span class="st_h">&#039;AKISMET_RRD_TS&#039;</span><span class="sy0">,</span> 300<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="kw2">function</span> akismet_update_rrd<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="re0">$last_update</span> <span class="sy0">=</span> get_option<span class="br0">&#40;</span> <span class="st_h">&#039;akismet_stat_last_update&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; <span class="re0">$current_time</span> <span class="sy0">=</span> <a href="http://www.php.net/strtotime"><span class="kw3">strtotime</span></a><span class="br0">&#40;</span>current_time<span class="br0">&#40;</span><span class="st_h">&#039;mysql&#039;</span><span class="sy0">,</span> 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$last_update</span> <span class="sy0">==</span> 0<span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$last_update</span> <span class="sy0">=</span> <span class="re0">$current_time</span> <span class="sy0">-</span> <span class="br0">&#40;</span>AKISMET_RRD_TS <span class="sy0">*</span> 200<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; <span class="re0">$time_diff</span> <span class="sy0">=</span> <span class="re0">$current_time</span> <span class="sy0">-</span> <span class="re0">$last_update</span><span class="sy0">;</span><br />
&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> <span class="re0">$time_diff</span> <span class="sy0">&gt;</span> AKISMET_RRD_TS <span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; update_option<span class="br0">&#40;</span> <span class="st_h">&#039;akismet_stat_last_update&#039;</span><span class="sy0">,</span> <span class="br0">&#40;</span><span class="re0">$current_time</span> <span class="sy0">-</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="re0">$time_diff</span> <span class="sy0">-</span> AKISMET_RRD_TS<span class="br0">&#41;</span> <span class="sy0">%</span> AKISMET_RRD_TS<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; akismet_create_rrd<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="kw2">global</span> <span class="re0">$wpdb</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">while</span><span class="br0">&#40;</span> <span class="re0">$last_update</span> <span class="sy0">&lt;</span> <span class="re0">$current_time</span> <span class="sy0">-</span> AKISMET_RRD_TS <span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="re0">$data</span> <span class="sy0">=</span> <span class="re0">$wpdb</span><span class="sy0">-&gt;</span><span class="me1">get_row</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT COUNT(1) as spam_count FROM <span class="es4">$wpdb-&gt;comments</span> WHERE comment_date_gmt BETWEEN FROM_UNIXTIME(&quot;</span> <span class="sy0">.</span> <span class="re0">$last_update</span> <span class="sy0">.</span> <span class="st0">&quot;) AND FROM_UNIXTIME(&quot;</span> <span class="sy0">.</span> <span class="br0">&#40;</span><span class="re0">$last_update</span> <span class="sy0">+</span> AKISMET_RRD_TS<span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st0">&quot;) AND comment_approved = &#039;spam&#039;&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="re0">$spam_count</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$spam_count</span> <span class="sy0">=</span> <span class="re0">$data</span><span class="sy0">-&gt;</span><span class="me1">spam_count</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; rrd_update<span class="br0">&#40;</span>AKISMET_RRD_FILE<span class="sy0">,</span> <span class="br0">&#40;</span><span class="re0">$last_update</span> <span class="sy0">+</span> <span class="br0">&#40;</span>get_settings<span class="br0">&#40;</span><span class="st_h">&#039;gmt_offset&#039;</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="nu0">3600</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st0">&quot;:<span class="es4">$spam_count</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; &nbsp; <span class="re0">$last_update</span> <span class="sy0">+=</span> AKISMET_RRD_TS<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw2">function</span> akismet_create_rrd<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> <span class="sy0">!</span><a href="http://www.php.net/file_exists"><span class="kw3">file_exists</span></a><span class="br0">&#40;</span>AKISMET_RRD_FILE<span class="br0">&#41;</span> <span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span> <span class="st0">&quot;&#8211;step&quot;</span><span class="sy0">,</span> AKISMET_RRD_TS<span class="sy0">,</span> <span class="st0">&quot;&#8211;start&quot;</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;DS:input:ABSOLUTE:600:0:100000&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:AVERAGE:0.5:1:600&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:AVERAGE:0.5:6:700&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:AVERAGE:0.5:24:775&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:AVERAGE:0.5:288:797&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:MAX:0.5:1:600&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:MAX:0.5:6:700&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:MAX:0.5:24:775&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:MAX:0.5:288:797&quot;</span><br />
&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; rrd_create<span class="br0">&#40;</span>AKISMET_RRD_FILE<span class="sy0">,</span> <span class="re0">$opts</span><span class="sy0">,</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$opts</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="sy1">?&gt;</span></div>
</div>
<p>The next step is the code to create graphs from the RRD in the file akismet_graph.php. This code registers the menu for WordPress in the Dashboard area and when displayed will generate the graphs for a day, month and year.</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span><br />
<span class="kw1">include_once</span> <span class="br0">&#40;</span><span class="st0">&quot;akismet_rrd.php&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><a href="http://www.php.net/define"><span class="kw3">define</span></a><span class="br0">&#40;</span><span class="st_h">&#039;AKISMET_GRAPH_DIR&#039;</span><span class="sy0">,</span> ABSPATH <span class="sy0">.</span> <span class="st_h">&#039;wp-content/plugins/&#039;</span> <span class="sy0">.</span> <a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span>plugin_basename<span class="br0">&#40;</span><span class="kw4">__FILE__</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">&#039;/&#039;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>add_action<span class="br0">&#40;</span><span class="st_h">&#039;activity_box_end&#039;</span><span class="sy0">,</span> <span class="st_h">&#039;akismet_stats&#039;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="kw2">function</span> wp_akstat_add_pages<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/function_exists"><span class="kw3">function_exists</span></a><span class="br0">&#40;</span><span class="st_h">&#039;add_submenu_page&#039;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add_submenu_page<span class="br0">&#40;</span><span class="st_h">&#039;index.php&#039;</span><span class="sy0">,</span> <span class="st_h">&#039;Akismet Graphs&#039;</span><span class="sy0">,</span> <span class="st_h">&#039;Akismet Graphs&#039;</span><span class="sy0">,</span> 1<span class="sy0">,</span> <span class="kw4">__FILE__</span><span class="sy0">,</span> displayit<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
add_action<span class="br0">&#40;</span><span class="st_h">&#039;admin_menu&#039;</span><span class="sy0">,</span> <span class="st_h">&#039;wp_akstat_add_pages&#039;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="kw2">function</span> displayit<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
akismet_update_rrd<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span> <span class="st0">&quot;&#8211;start&quot;</span><span class="sy0">,</span> <span class="st0">&quot;-1d&quot;</span><span class="sy0">,</span> <span class="st0">&quot;&#8211;title=Hourly Spam Graph&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;DEF:inspams=&quot;</span> <span class="sy0">.</span> AKISMET_RRD_FILE <span class="sy0">.</span><span class="st0">&quot;:input:AVERAGE&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;CDEF:hr=inspams,720,*&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;LINE2:hr#00FF00:Spams/Hour&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;COMMENT:<span class="es1">\\</span>n&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:hr:AVERAGE:Avg Spams/Hour\: %6.2lf&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;COMMENT: &nbsp;&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:hr:MAX:Max Spams/Hour\: %6.2lf<span class="es1">\\</span>r&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>rrd_graph<span class="br0">&#40;</span>AKISMET_GRAPH_DIR <span class="sy0">.</span> <span class="st0">&quot;akismet_1d.gif&quot;</span><span class="sy0">,</span> <span class="re0">$opts</span><span class="sy0">,</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$opts</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span> <span class="st0">&quot;&#8211;start&quot;</span><span class="sy0">,</span> <span class="st0">&quot;-1m&quot;</span><span class="sy0">,</span> <span class="st0">&quot;&#8211;title=Daily Spam Graph&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;DEF:inspams=&quot;</span> <span class="sy0">.</span> AKISMET_RRD_FILE <span class="sy0">.</span><span class="st0">&quot;:input:AVERAGE&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;CDEF:dy=inspams,8640,*&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;LINE2:dy#00FF00:Spams/Day&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;COMMENT:<span class="es1">\\</span>n&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:dy:AVERAGE:Avg Spams/Day\: %6.2lf&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;COMMENT: &nbsp;&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:dy:MAX:Max Spams/Day\: %6.2lf<span class="es1">\\</span>r&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>rrd_graph<span class="br0">&#40;</span>AKISMET_GRAPH_DIR <span class="sy0">.</span> <span class="st0">&quot;akismet_1m.gif&quot;</span><span class="sy0">,</span> <span class="re0">$opts</span><span class="sy0">,</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$opts</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span> <span class="st0">&quot;&#8211;start&quot;</span><span class="sy0">,</span> <span class="st0">&quot;-1y&quot;</span><span class="sy0">,</span> <span class="st0">&quot;&#8211;title=Monthly Spam Graph&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;DEF:inspams=&quot;</span> <span class="sy0">.</span> AKISMET_RRD_FILE <span class="sy0">.</span><span class="st0">&quot;:input:AVERAGE&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;CDEF:dy=inspams,8640,*&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;LINE2:dy#00FF00:Spams/Day&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;COMMENT:<span class="es1">\\</span>n&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:dy:AVERAGE:Avg Spams/Day\: %6.2lf&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;COMMENT: &nbsp;&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:dy:MAX:Max Spams/Day\: %6.2lf<span class="es1">\\</span>r&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>rrd_graph<span class="br0">&#40;</span>AKISMET_GRAPH_DIR <span class="sy0">.</span> <span class="st0">&quot;akismet_1y.gif&quot;</span><span class="sy0">,</span> <span class="re0">$opts</span><span class="sy0">,</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$opts</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$img_loc</span> <span class="sy0">=</span> <span class="st0">&quot;/wp-content/plugins/&quot;</span> <span class="sy0">.</span> <a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span>plugin_basename<span class="br0">&#40;</span><span class="kw4">__FILE__</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st0">&quot;/&quot;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></p>
<p>&lt;div style=&quot;text-align:center; padding: 5px;&quot;&gt;<br />
&lt;img src=&quot;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$img_loc</span> <span class="sy1">?&gt;</span>akismet_1d.gif&quot;/&gt; &lt;br/&gt;<br />
&lt;img src=&quot;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$img_loc</span> <span class="sy1">?&gt;</span>akismet_1m.gif&quot;/&gt; &lt;br/&gt;<br />
&lt;img src=&quot;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$img_loc</span> <span class="sy1">?&gt;</span>akismet_1y.gif&quot;/&gt; &lt;br/&gt;<br />
&lt;/div&gt;</p>
<p><span class="kw2">&lt;?php</span><br />
<span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>The final step is to make some changes to akismet.php to add the update functionality.</p>
<p>Put this at the top:</p>
<p>include_once (&#034;akismet_rrd.php&#034;);<br />
include(&#039;akismet_graph.php&#039;);</p>
<p>Every place you find &#034;DELETE FROM&#034; add the following before it:</p>
<p>akismet_update_rrd();</p>
<p>And finally here is what you will end up with after a few days:</p>
<p><img src="/examples/akismet-graph/akismet_1d.gif"/> <br/><br />
<img src="/examples/akismet-graph/akismet_1m.gif"/> <br/><br />
<img src="/examples/akismet-graph/akismet_1y.gif"/> <br/></p>
<p>One downside to the way this setup works is that you can miss some data if you delete quicker than the step time. I figured that was ok since the graphs are averages, the step is only 5 minutes and most people probably don&#039;t purge their spam that quickly.</p>
<p>Tags: <a href="http://technorati.com/tag/php" rel="tag">php</a>, <a href="http://technorati.com/tag/akismet" rel="tag"> akismet</a>, <a href="http://technorati.com/tag/rrd" rel="tag"> rrd</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/php/113/akismet-spam-graphs-with-php-rrd/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Flash video metadata to display annotations</title>
		<link>http://www.ioncannon.net/php/110/using-flash-video-metadata-to-display-annotations/</link>
		<comments>http://www.ioncannon.net/php/110/using-flash-video-metadata-to-display-annotations/#comments</comments>
		<pubDate>Sat, 09 Dec 2006 19:58:30 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[utilities]]></category>
		<category><![CDATA[web design]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/php/110/using-flash-video-metadata-to-display-annotations/</guid>
		<description><![CDATA[Now that you can create a streaming Flash video player with PHP or Ruby and you know add metadata for cuepoints to Flash videos you are ready for something else. The following code will show you how to create a video player with PHP that will watch for metadata events and display annotations contained inside [...]]]></description>
			<content:encoded><![CDATA[<p>Now that you can <a href="http://www.ioncannon.net/ruby/108/flash-video-steam-ming-php-ruby/">create a streaming Flash video player with PHP or Ruby</a> and you know <a href="http://www.ioncannon.net/web-design/109/metadata-cuepoint-flash-video-flvtool/">add metadata for cuepoints to Flash videos</a> you are ready for something else. The following code will show you how to create a video player with PHP that will watch for metadata events and display annotations contained inside the metadata either over the video itself or in a div on the same page as the movie.<br />
<span id="more-110"></span></p>
<p>The first steps are to create your Flash video if you haven&#039;t already and then add the metadata to it. See my post on <a href="http://www.ioncannon.net/web-design/109/metadata-cuepoint-flash-video-flvtool/">adding cuepoint metadata with flvtool2</a> if you want to know more on how to create the Flash video and add the metadata. I&#039;m using the same video from that post but a different set of metadata. </p>
<p>Here is the metadata I&#039;ve added to the video for the following examples:</p>
<div class="codesnip-container" >
<div class="xml codesnip" style="font-family:monospace;"><span class="sc3"><span class="re1">&lt;tags<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;metatag</span> <span class="re0">event</span>=<span class="st0">&quot;onCuePoint&quot;</span> <span class="re0">overwrite</span>=<span class="st0">&quot;true&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;name<span class="re2">&gt;</span></span></span>Cue Point 1<span class="sc3"><span class="re1">&lt;/name<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;timestamp<span class="re2">&gt;</span></span></span>4000<span class="sc3"><span class="re1">&lt;/timestamp<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;parameters<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;mydata<span class="re2">&gt;</span></span></span>Some data 1<span class="sc3"><span class="re1">&lt;/mydata<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/parameters<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;type<span class="re2">&gt;</span></span></span>event<span class="sc3"><span class="re1">&lt;/type<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/metatag<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;metatag</span> <span class="re0">event</span>=<span class="st0">&quot;onCuePoint&quot;</span> <span class="re0">overwrite</span>=<span class="st0">&quot;true&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;name<span class="re2">&gt;</span></span></span>Cue Point 2<span class="sc3"><span class="re1">&lt;/name<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;timestamp<span class="re2">&gt;</span></span></span>8000<span class="sc3"><span class="re1">&lt;/timestamp<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;parameters<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;mydata<span class="re2">&gt;</span></span></span>Some data 2<span class="sc3"><span class="re1">&lt;/mydata<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/parameters<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;type<span class="re2">&gt;</span></span></span>event<span class="sc3"><span class="re1">&lt;/type<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/metatag<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;metatag</span> <span class="re0">event</span>=<span class="st0">&quot;onCuePoint&quot;</span> <span class="re0">overwrite</span>=<span class="st0">&quot;true&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;name<span class="re2">&gt;</span></span></span>Cue Point 3<span class="sc3"><span class="re1">&lt;/name<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;timestamp<span class="re2">&gt;</span></span></span>12000<span class="sc3"><span class="re1">&lt;/timestamp<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;parameters<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;mydata<span class="re2">&gt;</span></span></span>Some data 3<span class="sc3"><span class="re1">&lt;/mydata<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/parameters<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;type<span class="re2">&gt;</span></span></span>event<span class="sc3"><span class="re1">&lt;/type<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/metatag<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;metatag</span> <span class="re0">event</span>=<span class="st0">&quot;onCuePoint&quot;</span> <span class="re0">overwrite</span>=<span class="st0">&quot;true&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;name<span class="re2">&gt;</span></span></span>Cue Point 4<span class="sc3"><span class="re1">&lt;/name<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;timestamp<span class="re2">&gt;</span></span></span>16000<span class="sc3"><span class="re1">&lt;/timestamp<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;parameters<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;mydata<span class="re2">&gt;</span></span></span>Some data 4<span class="sc3"><span class="re1">&lt;/mydata<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/parameters<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;type<span class="re2">&gt;</span></span></span>event<span class="sc3"><span class="re1">&lt;/type<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/metatag<span class="re2">&gt;</span></span></span><br />
<span class="sc3"><span class="re1">&lt;/tags<span class="re2">&gt;</span></span></span></div>
</div>
<p>The main thing to notice here is that the <b>type</b> for each metatag is <i>event</i> and in the <b>parameters</b> list there is a tag called <b>mydata</b> that contains some text. The text inside <b>mydata</b> is what we will be using for annotations. This tag can be called anything you like and you can have more than one.</p>
<p>I am using icons from the <a href="http://www.famfamfam.com/lab/icons/silk/preview.php">famfamfam silk</a> collection in the following examples. You will want to download them before trying these examples. </p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">wget http://www.famfamfam.com/lab/icons/silk/icons/control_pause.png<br />
wget http://www.famfamfam.com/lab/icons/silk/icons/control_pause_blue.png<br />
wget http://www.famfamfam.com/lab/icons/silk/icons/control_start.png<br />
wget http://www.famfamfam.com/lab/icons/silk/icons/control_start_blue.png<br />
wget http://www.famfamfam.com/lab/icons/silk/icons/control_play.png<br />
wget http://www.famfamfam.com/lab/icons/silk/icons/control_play_blue.png</div>
</div>
<p>The first example will display the annotation over the video itself. Here is the PHP code for generating the Flash player to display the annotations:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span><br />
<span class="kw2">function</span> createImage<span class="br0">&#40;</span><span class="re0">$img</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="re0">$shape</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFShape<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">setRightFill</span><span class="br0">&#40;</span><span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">addFill</span><span class="br0">&#40;</span><span class="kw2">new</span> SWFBitmap<span class="br0">&#40;</span><a href="http://www.php.net/fopen"><span class="kw3">fopen</span></a><span class="br0">&#40;</span><span class="re0">$img</span><span class="sy0">,</span> <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">drawLine</span><span class="br0">&#40;</span>16<span class="sy0">,</span>0<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">drawLine</span><span class="br0">&#40;</span>0<span class="sy0">,</span>16<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">drawLine</span><span class="br0">&#40;</span><span class="sy0">-</span>16<span class="sy0">,</span>0<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">drawLine</span><span class="br0">&#40;</span>0<span class="sy0">,-</span>16<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="kw1">return</span> <span class="re0">$shape</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw2">function</span> createButton<span class="br0">&#40;</span><span class="re0">$movie</span><span class="sy0">,</span> <span class="re0">$name</span><span class="sy0">,</span> <span class="re0">$loc</span><span class="sy0">,</span> <span class="re0">$script</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="re0">$button</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFButton<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$button</span><span class="sy0">-&gt;</span><span class="me1">addShape</span><span class="br0">&#40;</span>createImage<span class="br0">&#40;</span><span class="st0">&quot;control_&quot;</span> <span class="sy0">.</span> <span class="re0">$name</span> <span class="sy0">.</span> <span class="st0">&quot;.png&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> SWFBUTTON_UP<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$button</span><span class="sy0">-&gt;</span><span class="me1">addShape</span><span class="br0">&#40;</span>createImage<span class="br0">&#40;</span><span class="st0">&quot;control_&quot;</span> <span class="sy0">.</span> <span class="re0">$name</span> <span class="sy0">.</span> <span class="st0">&quot;_blue.png&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> SWFBUTTON_DOWN <span class="sy0">|</span> SWFBUTTON_HIT <span class="sy0">|</span> SWFBUTTON_OVER<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$button</span><span class="sy0">-&gt;</span><span class="me1">addAction</span><span class="br0">&#40;</span><span class="kw2">new</span> SWFAction<span class="br0">&#40;</span><span class="re0">$script</span><span class="br0">&#41;</span><span class="sy0">,</span> SWFBUTTON_HIT<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$item</span><span class="sy0">=</span><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$button</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$item</span><span class="sy0">-&gt;</span><span class="me1">moveto</span><span class="br0">&#40;</span><span class="re0">$loc</span><span class="sy0">,</span>248<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></p>
<p><a href="http://www.php.net/ming_setscale"><span class="kw3">Ming_setScale</span></a><span class="br0">&#40;</span>20<span class="sy0">.</span>0000000<span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/ming_useswfversion"><span class="kw3">ming_useswfversion</span></a><span class="br0">&#40;</span>7<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$movie</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFMovie<span class="br0">&#40;</span>7<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">setDimension</span><span class="br0">&#40;</span>320<span class="sy0">,</span>270<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// width x height</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">setBackground</span><span class="br0">&#40;</span>0&#215;33<span class="sy0">,</span>0&#215;33<span class="sy0">,</span>0&#215;33<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">setRate</span><span class="br0">&#40;</span>8<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>createButton<span class="br0">&#40;</span><span class="re0">$movie</span><span class="sy0">,</span> <span class="st0">&quot;start&quot;</span><span class="sy0">,</span> <span class="nu0">10</span><span class="sy0">,</span> <span class="st0">&quot;_root.videoStream.seek(0);&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
createButton<span class="br0">&#40;</span><span class="re0">$movie</span><span class="sy0">,</span> <span class="st0">&quot;pause&quot;</span><span class="sy0">,</span> <span class="nu0">40</span><span class="sy0">,</span> <span class="st0">&quot;_root.videoStream.pause(true);&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
createButton<span class="br0">&#40;</span><span class="re0">$movie</span><span class="sy0">,</span> <span class="st0">&quot;play&quot;</span><span class="sy0">,</span> <span class="nu0">70</span><span class="sy0">,</span> <span class="st0">&quot;_root.videoStream.pause(false);&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$strAction</span> <span class="sy0">=</span> <span class="st0">&quot;<br />
this.createTextField(&#039;video_txt&#039;, 999, 0, 0, 100, 100);<br />
video_txt.autoSize = &#039;left&#039;;<br />
video_txt.multiline = true;<br />
video_txt.textColor = 0xeeeeee;</p>
<p>stop();<br />
nc=new NetConnection();<br />
nc.connect(null);<br />
videoStream=new NetStream(nc);<br />
videoStreamItem.attachVideo(videoStream);<br />
videoStream.setBufferTime(10);<br />
videoStream.play(&#039;http://localhost/test.flv&#039;);<br />
videoStream.pause();</p>
<p>videoStream.onCuePoint = function(infoObject)<br />
{<br />
&nbsp; video_txt.text = &#039;Name: &#039; + infoObject.name + &#039;<span class="es1">\n</span>&#039;;<br />
&nbsp; if( infoObject.parameters != undefined )<br />
&nbsp; {<br />
&nbsp; &nbsp; video_txt.text += &#039;Info: &#039; + infoObject.parameters['mydata'] + &#039;<span class="es1">\n</span>&#039;;<br />
&nbsp; }<br />
&nbsp; else<br />
&nbsp; {<br />
&nbsp; &nbsp; video_txt.text += &#039;Info: undef<span class="es1">\n</span>&#039;;<br />
&nbsp; }<br />
};<br />
&quot;</span><span class="sy0">;</span></p>
<p><span class="re0">$stream</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFVideoStream<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$stream</span><span class="sy0">-&gt;</span><span class="me1">setDimension</span><span class="br0">&#40;</span>320<span class="sy0">,</span> 240<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$item</span><span class="sy0">=</span><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$stream</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$item</span><span class="sy0">-&gt;</span><span class="me1">setName</span><span class="br0">&#40;</span><span class="st0">&quot;videoStreamItem&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="kw2">new</span> SWFAction<span class="br0">&#40;</span><span class="re0">$strAction</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">nextFrame</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">save</span><span class="br0">&#40;</span><span class="st0">&quot;test.swf&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>The following part of the above PHP is what connects the cuepoints to the overlay text. Notice the use of the <b>mydata</b> tag. The tag data is available in the parameters hash:</p>
<div class="codesnip-container" >
<div class="text codesnip" style="font-family:monospace;">videoStream.onCuePoint = function(infoObject)<br />
{<br />
&nbsp; video_txt.text = &#039;Name: &#039; + infoObject.name + &#039;\n&#039;;<br />
&nbsp; if( infoObject.parameters != undefined )<br />
&nbsp; {<br />
&nbsp; &nbsp; video_txt.text += &#039;Info: &#039; + infoObject.parameters['mydata'] + &#039;\n&#039;;<br />
&nbsp; }<br />
&nbsp; else<br />
&nbsp; {<br />
&nbsp; &nbsp; video_txt.text += &#039;Info: undef\n&#039;;<br />
&nbsp; }<br />
};</div>
</div>
<p>Here is the result (hit the play button to start the video):</p>
<p><object type="application/x-shockwave-flash" data="http://d28nuaxr58rcpu.cloudfront.net/annotation-examples/test1.swf" width="320" height="270" id="go1"><param name="movie" value="http://d28nuaxr58rcpu.cloudfront.net/annotation-examples/test1.swf" /><param name="quality" value="high" /></object></p>
<p>The following examples is the same as the above example except that it uses a javascript call to display the annotation data in a div on the page:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span><br />
<span class="kw2">function</span> createImage<span class="br0">&#40;</span><span class="re0">$img</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="re0">$shape</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFShape<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">setRightFill</span><span class="br0">&#40;</span><span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">addFill</span><span class="br0">&#40;</span><span class="kw2">new</span> SWFBitmap<span class="br0">&#40;</span><a href="http://www.php.net/fopen"><span class="kw3">fopen</span></a><span class="br0">&#40;</span><span class="re0">$img</span><span class="sy0">,</span> <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">drawLine</span><span class="br0">&#40;</span>16<span class="sy0">,</span>0<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">drawLine</span><span class="br0">&#40;</span>0<span class="sy0">,</span>16<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">drawLine</span><span class="br0">&#40;</span><span class="sy0">-</span>16<span class="sy0">,</span>0<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$shape</span><span class="sy0">-&gt;</span><span class="me1">drawLine</span><span class="br0">&#40;</span>0<span class="sy0">,-</span>16<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="kw1">return</span> <span class="re0">$shape</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="kw2">function</span> createButton<span class="br0">&#40;</span><span class="re0">$movie</span><span class="sy0">,</span> <span class="re0">$name</span><span class="sy0">,</span> <span class="re0">$loc</span><span class="sy0">,</span> <span class="re0">$script</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="re0">$button</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFButton<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$button</span><span class="sy0">-&gt;</span><span class="me1">addShape</span><span class="br0">&#40;</span>createImage<span class="br0">&#40;</span><span class="st0">&quot;control_&quot;</span> <span class="sy0">.</span> <span class="re0">$name</span> <span class="sy0">.</span> <span class="st0">&quot;.png&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> SWFBUTTON_UP<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$button</span><span class="sy0">-&gt;</span><span class="me1">addShape</span><span class="br0">&#40;</span>createImage<span class="br0">&#40;</span><span class="st0">&quot;control_&quot;</span> <span class="sy0">.</span> <span class="re0">$name</span> <span class="sy0">.</span> <span class="st0">&quot;_blue.png&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> SWFBUTTON_DOWN <span class="sy0">|</span> SWFBUTTON_HIT <span class="sy0">|</span> SWFBUTTON_OVER<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$button</span><span class="sy0">-&gt;</span><span class="me1">addAction</span><span class="br0">&#40;</span><span class="kw2">new</span> SWFAction<span class="br0">&#40;</span><span class="re0">$script</span><span class="br0">&#41;</span><span class="sy0">,</span> SWFBUTTON_HIT<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$item</span><span class="sy0">=</span><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$button</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$item</span><span class="sy0">-&gt;</span><span class="me1">moveto</span><span class="br0">&#40;</span><span class="re0">$loc</span><span class="sy0">,</span>248<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></p>
<p><a href="http://www.php.net/ming_setscale"><span class="kw3">Ming_setScale</span></a><span class="br0">&#40;</span>20<span class="sy0">.</span>0000000<span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/ming_useswfversion"><span class="kw3">ming_useswfversion</span></a><span class="br0">&#40;</span>7<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$movie</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFMovie<span class="br0">&#40;</span>7<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">setDimension</span><span class="br0">&#40;</span>320<span class="sy0">,</span>270<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// width x height</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">setBackground</span><span class="br0">&#40;</span>0&#215;33<span class="sy0">,</span>0&#215;33<span class="sy0">,</span>0&#215;33<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">setRate</span><span class="br0">&#40;</span>8<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>createButton<span class="br0">&#40;</span><span class="re0">$movie</span><span class="sy0">,</span> <span class="st0">&quot;start&quot;</span><span class="sy0">,</span> <span class="nu0">10</span><span class="sy0">,</span> <span class="st0">&quot;_root.videoStream.seek(0);&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
createButton<span class="br0">&#40;</span><span class="re0">$movie</span><span class="sy0">,</span> <span class="st0">&quot;pause&quot;</span><span class="sy0">,</span> <span class="nu0">40</span><span class="sy0">,</span> <span class="st0">&quot;_root.videoStream.pause(true);&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
createButton<span class="br0">&#40;</span><span class="re0">$movie</span><span class="sy0">,</span> <span class="st0">&quot;play&quot;</span><span class="sy0">,</span> <span class="nu0">70</span><span class="sy0">,</span> <span class="st0">&quot;_root.videoStream.pause(false);&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$strAction</span> <span class="sy0">=</span> <span class="st0">&quot;<br />
this.createTextField(&#039;video_txt&#039;, 999, 0, 0, 100, 100);<br />
video_txt.autoSize = &#039;left&#039;;<br />
video_txt.multiline = true;<br />
video_txt.textColor = 0xeeeeee;</p>
<p>stop();<br />
nc=new NetConnection();<br />
nc.connect(null);<br />
videoStream=new NetStream(nc);<br />
videoStreamItem.attachVideo(videoStream);<br />
videoStream.setBufferTime(10);<br />
videoStream.play(&#039;http://localhost/test.flv&#039;);<br />
videoStream.pause();</p>
<p>videoStream.onCuePoint = function(infoObject)<br />
{<br />
&nbsp; if( infoObject.parameters != undefined )<br />
&nbsp; {<br />
&nbsp; &nbsp; geturl(&#039;javascript:aTestCall(\&#034; + infoObject.parameters['mydata'] + &#039;\&#039;)');<br />
&nbsp; }<br />
};<br />
&quot;</span><span class="sy0">;</span></p>
<p><span class="re0">$stream</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFVideoStream<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$stream</span><span class="sy0">-&gt;</span><span class="me1">setDimension</span><span class="br0">&#40;</span>320<span class="sy0">,</span> 240<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$item</span><span class="sy0">=</span><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$stream</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$item</span><span class="sy0">-&gt;</span><span class="me1">setName</span><span class="br0">&#40;</span><span class="st0">&quot;videoStreamItem&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="kw2">new</span> SWFAction<span class="br0">&#40;</span><span class="re0">$strAction</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">nextFrame</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">save</span><span class="br0">&#40;</span><span class="st0">&quot;test.swf&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>This javascript will display the data in the div (note that this won&#039;t work for all browsers, I&#039;m just making it simple):</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="kw2">function</span> aTestCall<span class="br0">&#40;</span>data<span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">&quot;infoDisplayArea&quot;</span><span class="br0">&#41;</span>.<span class="me1">innerHTML</span> <span class="sy0">=</span> data<span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span></div>
</div>
<p>This is how you would set up the div to display the data:</p>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/div.html"><span class="kw2">div</span></a> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;infoDisplayArea&quot;</span> <span class="kw3">style</span><span class="sy0">=</span><span class="st0">&quot;border: solid 1px #000; padding: 5px 5px 5px 5px; width: 50%;&quot;</span>&gt;</span><br />
No data yet&#8230;<br />
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/div.html"><span class="kw2">div</span></a>&gt;</span></div>
</div>
<p>Here is the result (hit the play button to start the video):</p>
<p><script type="text/javascript">//<!--
function aTestCall(data){document.getElementById("infoDisplayArea").innerHTML = data;} // --></script></p>
<p><object type="application/x-shockwave-flash" data="http://d28nuaxr58rcpu.cloudfront.net/annotation-examples/test2.swf" width="320" height="270" id="go2"><param name="movie" value="http://d28nuaxr58rcpu.cloudfront.net/annotation-examples/test2.swf" /><param name="quality" value="high" /></object></p>
<div id="infoDisplayArea" style="border: solid 1px #000; padding: 5px 5px 5px 5px; width: 50%;">
No data yet&#8230;
</div>
<p>Keep an eye on the above box while the video is playing to see the annotations.</p>
<p>Tags: <a href="http://technorati.com/tag/flash" rel="tag">flash</a>, <a href="http://technorati.com/tag/flash+video" rel="tag"> flash video</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/php/110/using-flash-video-metadata-to-display-annotations/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>How to Create a Streaming Flash Video Player Using Ming PHP or Ruby</title>
		<link>http://www.ioncannon.net/ruby/108/flash-video-steam-ming-php-ruby/</link>
		<comments>http://www.ioncannon.net/ruby/108/flash-video-steam-ming-php-ruby/#comments</comments>
		<pubDate>Wed, 29 Nov 2006 19:52:32 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[utilities]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/ruby/108/flash-video-steam-ming-php-ruby/</guid>
		<description><![CDATA[I mentioned in creating Flash videos using FFMpeg that you could use Ming to create your own Flash video player. I&#039;ve added a patch to the ruby -ming extension for video streaming so now it is possible to create a streaming player with both PHP and Ruby using their Ming extensions. The following examples show [...]]]></description>
			<content:encoded><![CDATA[<p>I mentioned in <a href="http://www.ioncannon.net/linux/105/create-flash-videos-ffmpeg/">creating Flash videos using FFMpeg</a> that you could use Ming to create your own Flash video player. I&#039;ve added a patch to the <a href="http://www.ioncannon.net/ruby/107/ruby-ming-extension-patch-to-add-video-streaming/">ruby -ming extension for video streaming</a> so now it is possible to create a streaming player with both PHP and Ruby using their Ming extensions. The following examples show you how.<br />
<span id="more-108"></span></p>
<p>First a little background. You can read about <a href="http://livedocs.macromedia.com/flash/mx2004/main_7_2/00001107.html">playing back external FLV files dynamically</a> with actionscript at the Macromedia website. It includes references to the <a href="http://livedocs.macromedia.com/flash/mx2004/main_7_2/00001587.html">NetConnect class</a> and <a href="http://livedocs.macromedia.com/flash/mx2004/main_7_2/00001589.html">NetStream class</a> that together let you stream a FLV file. The main thing Ming does for you in the following simple examples is give you a SWF with a video player in it and let you attach some action script to it.</p>
<p>Here is how you do it in PHP:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span><br />
<a href="http://www.php.net/ming_setscale"><span class="kw3">Ming_setScale</span></a><span class="br0">&#40;</span>10<span class="sy0">.</span>0000000<span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/ming_useswfversion"><span class="kw3">ming_useswfversion</span></a><span class="br0">&#40;</span>7<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$movie</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFMovie<span class="br0">&#40;</span>7<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">setDimension</span><span class="br0">&#40;</span>320<span class="sy0">,</span>240<span class="br0">&#41;</span><span class="sy0">;</span> <br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">setBackground</span><span class="br0">&#40;</span>0&#215;33<span class="sy0">,</span>0&#215;33<span class="sy0">,</span>0&#215;33<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">setRate</span><span class="br0">&#40;</span>8<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$strAction</span> <span class="sy0">=</span> <span class="st0">&quot;<br />
stop();<br />
netConn=new NetConnection();<br />
netConn.connect(null);<br />
vStream=new NetStream(netConn);<br />
video1.attachVideo(vStream);<br />
vStream.setBufferTime(10);<br />
vStream.play(&#039;http://localhost/test.flv&#039;);<br />
&quot;</span><span class="sy0">;</span></p>
<p><span class="re0">$stream</span> <span class="sy0">=</span> <span class="kw2">new</span> SWFVideoStream<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$item</span><span class="sy0">=</span><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$stream</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$item</span><span class="sy0">-&gt;</span><span class="me1">setname</span><span class="br0">&#40;</span><span class="st0">&quot;video1&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="kw2">new</span> SWFAction<span class="br0">&#40;</span><span class="re0">$strAction</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">nextFrame</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="re0">$movie</span><span class="sy0">-&gt;</span><span class="me1">save</span><span class="br0">&#40;</span><span class="st0">&quot;videostream.swf&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>And here is how you do it with Ruby:</p>
<div class="codesnip-container" >
<div class="ruby codesnip" style="font-family:monospace;"><span class="co1">#!/usr/bin/env ruby</span></p>
<p><span class="kw3">require</span> <span class="st0">&#039;ming/ming&#039;</span><br />
<span class="kw1">include</span> Ming</p>
<p>Ming::set_scale<span class="br0">&#40;</span><span class="nu0">10.0000000</span><span class="br0">&#41;</span></p>
<p>movie = SWFMovie.<span class="me1">new</span><span class="br0">&#40;</span><span class="nu0">7</span><span class="br0">&#41;</span><br />
movie.<span class="me1">set_background</span><span class="br0">&#40;</span>0xff, 0xff, 0xff<span class="br0">&#41;</span><br />
movie.<span class="me1">set_dimension</span><span class="br0">&#40;</span><span class="nu0">320</span>, <span class="nu0">240</span><span class="br0">&#41;</span><br />
movie.<span class="me1">set_rate</span><span class="br0">&#40;</span><span class="nu0">8</span><span class="br0">&#41;</span></p>
<p>strAction = <span class="st0">&#039;<br />
stop();<br />
netConn=new NetConnection();<br />
netConn.connect(null);<br />
vStream=new NetStream(netConn);<br />
video1.attachVideo(vStream);<br />
vStream.setBufferTime(10);<br />
vStream.play(<span class="es0">\&#039;</span>http://localhost/test.flv<span class="es0">\&#039;</span>);<br />
&#039;</span></p>
<p>vstream = SWFVideoStream.<span class="me1">new</span><br />
item = movie.<span class="me1">add</span><span class="br0">&#40;</span>vstream<span class="br0">&#41;</span></p>
<p>item.<span class="me1">set_name</span><span class="br0">&#40;</span><span class="st0">&quot;video1&quot;</span><span class="br0">&#41;</span><br />
movie.<span class="me1">add</span><span class="br0">&#40;</span>SWFAction.<span class="me1">new</span><span class="br0">&#40;</span>strAction<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
movie.<span class="me1">next_frame</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>movie.<span class="me1">save</span><span class="br0">&#40;</span><span class="st0">&quot;videostream.swf&quot;</span><span class="br0">&#41;</span></div>
</div>
<p>Here is the result of the above examples:</p>
<div>
<object type="application/x-shockwave-flash" data="http://d28nuaxr58rcpu.cloudfront.net/ming/videostream.swf" width="192" height="154" id="go"><param name="movie" value="http://d28nuaxr58rcpu.cloudfront.net/ming/videostream.swf" /><param name="quality" value="high" /></object>
</div>
<p>Tags: <a href="http://technorati.com/tag/flash" rel="tag">flash</a>, <a href="http://technorati.com/tag/php" rel="tag"> php</a>, <a href="http://technorati.com/tag/ruby" rel="tag"> ruby</a>, <a href="http://technorati.com/tag/flv" rel="tag"> flv</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/ruby/108/flash-video-steam-ming-php-ruby/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PHP ImageMagick MagickWand Examples</title>
		<link>http://www.ioncannon.net/php/61/php-imagemagick-magickwand-examples/</link>
		<comments>http://www.ioncannon.net/php/61/php-imagemagick-magickwand-examples/#comments</comments>
		<pubDate>Thu, 23 Nov 2006 14:11:16 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/php/61/php-imagemagick-magickwand-examples/</guid>
		<description><![CDATA[A while back I explained how to compile the ImageMagick extension for PHP and this past week I got around to creating some example code to make some of the command line examples I have in ImageMagick command line examples part 1 and ImageMagick command line examples part 2. The first step of course is [...]]]></description>
			<content:encoded><![CDATA[<p>A while back I explained <a href="http://www.ioncannon.net/php/75/how-to-compile-imagemagick-for-php-by-hand/">how to compile the ImageMagick extension for PHP</a> and this past week I got around to creating some example code to make some of the command line examples I have in <a href="http://www.ioncannon.net/linux/81/5-imagemagick-command-line-examples-part-1/">ImageMagick command line examples part 1</a> and <a href="http://www.ioncannon.net/linux/72/5-imagemagick-command-line-examples-part-2/">ImageMagick command line examples part 2</a>.<br />
<span id="more-61"></span></p>
<p>The first step of course is to make sure the MagickWand extension is installed. You will want to verify that it is listed in a phpinfo() call before trying any of these examples. After verifying that you have the extension installed you might want to read an <a href="http://www.sitepoint.com/article/dynamic-images-imagemagick">introduction to using MagickWand</a> before looking at these examples. And of course you will want to know where the <a href="http://www.bitweaver.org/doc/magickwand/index.html">MagickWand reference documentation</a> is once you are ready to try more.</p>
<p>For more information on the options used in these examples it is best to look at their corresponding command line example.</p>
<h2>Example 1: Simple Annotate</h2>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p><span class="co1">// convert flower.jpg -font courier -fill white -pointsize 20 -annotate +50+50 Flower flower_annotate1.jpg</span></p>
<p><span class="re0">$resource</span> <span class="sy0">=</span> NewMagickWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$dwand</span> <span class="sy0">=</span> NewDrawingWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$pwand</span> <span class="sy0">=</span> NewPixelWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>PixelSetColor<span class="br0">&#40;</span><span class="re0">$pwand</span><span class="sy0">,</span> <span class="st0">&quot;white&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
DrawSetFont<span class="br0">&#40;</span><span class="re0">$dwand</span><span class="sy0">,</span> <span class="st0">&quot;/usr/share/fonts/default/TrueType/cour.ttf&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
DrawSetFontSize<span class="br0">&#40;</span><span class="re0">$dwand</span><span class="sy0">,</span> 20<span class="br0">&#41;</span><span class="sy0">;</span><br />
DrawSetFillColor<span class="br0">&#40;</span><span class="re0">$dwand</span><span class="sy0">,</span> <span class="re0">$pwand</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>MagickReadImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="st_h">&#039;small_flower.jpg&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="kw1">if</span><span class="br0">&#40;</span> MagickAnnotateImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="re0">$dwand</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="st0">&quot;Flower&quot;</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <a href="http://www.php.net/header"><span class="kw3">header</span></a><span class="br0">&#40;</span> <span class="st_h">&#039;Content-Type: image/gif&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; MagickEchoImageBlob<span class="br0">&#40;</span> <span class="re0">$resource</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">echo</span> MagickGetExceptionString<span class="br0">&#40;</span><span class="re0">$resource</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="sy1">?&gt;</span></div>
</div>
<p>One note on the above is that I needed to specify the exact location of the font to get it to show up. I believe this isn&#039;t always needed but if you try to leave it out and nothing shows up you should try specifying the full path to the font.</p>
<h2>Example 2: Complex Annotate</h2>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p><span class="co1">// convert flower.jpg -fill white -box &quot;#00770080&quot; -gravity South -pointsize 20 -annotate +0+5 &quot; &nbsp; Flower &nbsp;&quot; flower_annotate2.jpg</span></p>
<p><span class="re0">$resource</span> <span class="sy0">=</span> NewMagickWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$dwand</span> <span class="sy0">=</span> NewDrawingWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$pwand</span> <span class="sy0">=</span> NewPixelWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>PixelSetColor<span class="br0">&#40;</span><span class="re0">$pwand</span><span class="sy0">,</span> <span class="st0">&quot;white&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
DrawSetFont<span class="br0">&#40;</span><span class="re0">$dwand</span><span class="sy0">,</span> <span class="st0">&quot;/usr/share/fonts/default/TrueType/cour.ttf&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
DrawSetFontSize<span class="br0">&#40;</span><span class="re0">$dwand</span><span class="sy0">,</span> 20<span class="br0">&#41;</span><span class="sy0">;</span><br />
DrawSetFillColor<span class="br0">&#40;</span><span class="re0">$dwand</span><span class="sy0">,</span> <span class="re0">$pwand</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>DrawSetGravity<span class="br0">&#40;</span><span class="re0">$dwand</span><span class="sy0">,</span> MW_SouthGravity<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>MagickReadImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="st_h">&#039;small_flower.jpg&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="kw1">if</span><span class="br0">&#40;</span> MagickAnnotateImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="re0">$dwand</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="st0">&quot;Flower&quot;</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <a href="http://www.php.net/header"><span class="kw3">header</span></a><span class="br0">&#40;</span> <span class="st_h">&#039;Content-Type: image/gif&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; MagickEchoImageBlob<span class="br0">&#40;</span> <span class="re0">$resource</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">echo</span> MagickGetExceptionString<span class="br0">&#40;</span><span class="re0">$resource</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="sy1">?&gt;</span></div>
</div>
<h2>Example 3: Crop an Area</h2>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p><span class="co1">// convert flower.jpg -crop 128&#215;128+50+50 flower_crop.jpg</span></p>
<p><span class="re0">$resource</span> <span class="sy0">=</span> NewMagickWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>MagickReadImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="st_h">&#039;small_flower.jpg&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="kw1">if</span><span class="br0">&#40;</span> MagickCropImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> 128<span class="sy0">,</span> 128<span class="sy0">,</span> 50<span class="sy0">,</span> 50 <span class="br0">&#41;</span> <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <a href="http://www.php.net/header"><span class="kw3">header</span></a><span class="br0">&#40;</span> <span class="st_h">&#039;Content-Type: image/gif&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; MagickEchoImageBlob<span class="br0">&#40;</span> <span class="re0">$resource</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">echo</span> MagickGetExceptionString<span class="br0">&#40;</span><span class="re0">$resource</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></p>
<p><span class="sy1">?&gt;</span></div>
</div>
<h2>Example 4: Rotate</h2>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p><span class="co1">// convert flower.jpg -rotate 45 flower_rotate45.jpg</span></p>
<p><span class="re0">$resource</span> <span class="sy0">=</span> NewMagickWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickReadImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="st_h">&#039;small_flower.jpg&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>MagickRotateImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="kw4">null</span><span class="sy0">,</span> 45 <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><a href="http://www.php.net/header"><span class="kw3">header</span></a><span class="br0">&#40;</span> <span class="st_h">&#039;Content-Type: image/gif&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickEchoImageBlob<span class="br0">&#40;</span> <span class="re0">$resource</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="sy1">?&gt;</span></div>
</div>
<h2>Example 5: Resize</h2>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p><span class="co1">// convert flower_original.jpg -resize 640&#215;480 flower.jpg</span></p>
<p><span class="re0">$resource</span> <span class="sy0">=</span> NewMagickWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickReadImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="st_h">&#039;small_flower.jpg&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>MagickResizeImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> 100<span class="sy0">,</span> 100<span class="sy0">,</span> MW_QuadraticFilter<span class="sy0">,</span> 1<span class="sy0">.</span>0 <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><a href="http://www.php.net/header"><span class="kw3">header</span></a><span class="br0">&#40;</span> <span class="st_h">&#039;Content-Type: image/gif&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickEchoImageBlob<span class="br0">&#40;</span> <span class="re0">$resource</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="sy1">?&gt;</span></div>
</div>
<h2>Example 6: Apply Resharp Filter</h2>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p><span class="co1">// convert flower.jpg -unsharp 1.5&#215;1.0+1.5+0.02 flower_unsharp.jpg</span></p>
<p><span class="re0">$resource</span> <span class="sy0">=</span> NewMagickWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickReadImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="st_h">&#039;small_flower.jpg&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>MagickUnsharpMaskImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> 1<span class="sy0">.</span>5<span class="sy0">,</span> 1<span class="sy0">.</span>0<span class="sy0">,</span> 1<span class="sy0">.</span>5<span class="sy0">,</span> 0<span class="sy0">.</span>02 <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><a href="http://www.php.net/header"><span class="kw3">header</span></a><span class="br0">&#40;</span> <span class="st_h">&#039;Content-Type: image/gif&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickEchoImageBlob<span class="br0">&#40;</span> <span class="re0">$resource</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="sy1">?&gt;</span></div>
</div>
<h2>Example 7: Compress JPG</h2>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p><span class="co1">// convert flower.jpg -quality 80% flower_quality.jpg</span></p>
<p><span class="re0">$resource</span> <span class="sy0">=</span> NewMagickWand<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickReadImage<span class="br0">&#40;</span> <span class="re0">$resource</span><span class="sy0">,</span> <span class="st_h">&#039;small_flower.jpg&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>MagickSetFormat<span class="br0">&#40;</span><span class="re0">$resource</span><span class="sy0">,</span> <span class="st_h">&#039;JPG&#039;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickSetImageCompression<span class="br0">&#40;</span><span class="re0">$resource</span><span class="sy0">,</span> MW_JPEGCompression<span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickSetImageCompressionQuality<span class="br0">&#40;</span><span class="re0">$resource</span><span class="sy0">,</span> 80<span class="sy0">.</span>0<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><a href="http://www.php.net/header"><span class="kw3">header</span></a><span class="br0">&#40;</span> <span class="st_h">&#039;Content-Type: image/gif&#039;</span> <span class="br0">&#41;</span><span class="sy0">;</span><br />
MagickEchoImageBlob<span class="br0">&#40;</span> <span class="re0">$resource</span> <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="sy1">?&gt;</span></div>
</div>
<p>Tags: <a href="http://technorati.com/tag/php" rel="tag">php</a>, <a href="http://technorati.com/tag/imagemagick" rel="tag"> imagemagick</a>, <a href="http://technorati.com/tag/graphics" rel="tag"> graphics</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/php/61/php-imagemagick-magickwand-examples/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to compile ImageMagick for PHP by hand</title>
		<link>http://www.ioncannon.net/php/75/how-to-compile-imagemagick-for-php-by-hand/</link>
		<comments>http://www.ioncannon.net/php/75/how-to-compile-imagemagick-for-php-by-hand/#comments</comments>
		<pubDate>Wed, 01 Nov 2006 00:33:34 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[web design]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/php/75/how-to-compile-imagemagick-for-php-by-hand/</guid>
		<description><![CDATA[Some time ago I was looking at how to re-size uploaded images in a way that looks good using PHP. I was impressed that when I uploaded a 4M picture to flickr it managed to re-size and compress it into a smaller version that looked correct. I knew they weren&#039;t just resizing it so I [...]]]></description>
			<content:encoded><![CDATA[<p>Some time ago I was looking at how to re-size uploaded images in a way that looks good using PHP. I was impressed that when I uploaded a 4M picture to flickr it managed to re-size and compress it into a smaller version that looked correct. I knew they weren&#039;t just resizing it so I went on a quest to find out what it took to do the same thing with PHP. The following is step one in that process.</p>
<p><span id="more-75"></span></p>
<p>My goal was to be able to convert a large image into a smaller one and have it look decent. I tried a few different approaches directly in PHP before I decided to see just how hard it was to do with a command line tool. I found that I could re-size and enhance a photos in a way that made them look pretty good using ImageMagick&#039;s re-size and sharpen (for more on doing this on the command line see my <a href="http://www.ioncannon.net/linux/72/5-imagemagick-command-line-examples-part-2/">ImageMagick command line examples</a>). </p>
<p>At this point I started looking into how to translate what I did on the command line into PHP. The first step was to get access to the ImageMagick libraries into PHP. The first step was to get MagickWand for PHP installed so that I could call the ImageMagick functions with PHP. There are a few other ways of calling ImageMagick out there but they all involved system calls to the convert command and I would rather use library calls. Here are the steps you need to get the MagicKWand extension installed:</p>
<ol>
<li>Install ImageMagick either from source or a binary. In my case I&#039;m running fedora so I just installed it with yum.</li>
<li>Download the <a href="http://www.magickwand.org/download/php/">MagickWand extension</a> for PHP.</li>
<li>Go to your PHP source directory and find the ext directory under it. In the ext directory expand the extension.</li>
<li>Change directories into the magickwand directory under ext and run phpize.</li>
<li>Change back to the root PHP source directory and remove the current configuration file: rm -f ./configure</li>
<li>In the root PHP source directory run ./buildconf &#8211;force to rebuild the configuration script</li>
<li>You can verify the configuration file was created correctly by looking for magickwand in the new configure script: grep magickwand configure</li>
<li>Now reconfigure your PHP. Use the flag &#8211;with-magickwand=<directory to ImageMagick> to enable MagickWand. For me the directory to ImageMagick was /usr</li>
<li>Now you can recompile PHP and reinstall it. You should find MagickWand listed in a phpinfo() once it is compiled in correctly.</li>
</ol>
<p>Next time I will go into how to use PHP to do some of the tricks you can do with ImageMagick on the command line.</p>
<p>Tags: <a href="http://technorati.com/tag/ImageMagick" rel="tag">ImageMagick</a>, <a href="http://technorati.com/tag/PHP" rel="tag"> PHP</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/php/75/how-to-compile-imagemagick-for-php-by-hand/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Lighty XCache for PHP</title>
		<link>http://www.ioncannon.net/php/96/lighty-xcache-for-php/</link>
		<comments>http://www.ioncannon.net/php/96/lighty-xcache-for-php/#comments</comments>
		<pubDate>Tue, 19 Sep 2006 01:50:17 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/php/96/lighty-xcache-for-php/</guid>
		<description><![CDATA[I noticed Lighty XCache when it came out a few months ago. I like EAccelerator myself but now there is an admin console for XCache that looks pretty nice.]]></description>
			<content:encoded><![CDATA[<p>I noticed <a href="http://blog.lighttpd.net/articles/2006/04/04/one-more-opcache-for-php-preview">Lighty XCache</a> when it came out a few months ago. I like EAccelerator myself but now there is an <a href="http://blog.lighttpd.net/articles/2006/09/17/xcaches-demo">admin console for XCache</a> that looks pretty nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/php/96/lighty-xcache-for-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to map URLs with PHP and lighttpd</title>
		<link>http://www.ioncannon.net/system-administration/95/how-to-map-urls-with-php-and-lighttpd/</link>
		<comments>http://www.ioncannon.net/system-administration/95/how-to-map-urls-with-php-and-lighttpd/#comments</comments>
		<pubDate>Tue, 22 Aug 2006 18:52:00 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[system administration]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/system-administration/95/how-to-map-urls-with-php-and-lighttpd/</guid>
		<description><![CDATA[On a number of occasions I&#039;ve wanted to map a section of a site hosted with lighttpd onto a single PHP file that could then be used as a controller. Here is how I go about doing it. The first part is to re-write the given part of the site to the PHP file you [...]]]></description>
			<content:encoded><![CDATA[<p>On a number of occasions I&#039;ve wanted to map a section of a site hosted with lighttpd onto a single PHP file that could then be used as a controller. Here is how I go about doing it.</p>
<p>The first part is to re-write the given part of the site to the PHP file you want to be the controller. Add the following to your configuration file:</p>
<div class="codesnip-container" >
<div class="ini codesnip" style="font-family:monospace;">url.rewrite <span class="sy0">=</span><span class="re2"> <span class="br0">&#40;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;^/(.*)&quot;</span> <span class="sy0">=</span>&gt; <span class="st0">&quot;/controller.php&quot;</span><br />
&nbsp; <span class="br0">&#41;</span></div>
</div>
<p>You can then start with a simple example to see where you will get your URL information from:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span><br />
<span class="kw1">echo</span> <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st0">&quot;REQUEST_URI&quot;</span><span class="br0">&#93;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>The $_SERVER["REQUEST_URI"] value will be the requested URI. You can now break it up into multiple parts with <a href="http://us3.php.net/manual/en/function.explode.php">explode</a>:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span><br />
<span class="re0">$urlParts</span> <span class="sy0">=</span> <a href="http://www.php.net/explode"><span class="kw3">explode</span></a><span class="br0">&#40;</span><span class="st0">&quot;/&quot;</span><span class="sy0">,</span> <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st_h">&#039;REQUEST_URI&#039;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">echo</span> <span class="re0">$urlParts</span><span class="br0">&#91;</span>1<span class="br0">&#93;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>At this point you have an array of the URI parts and can map those however you want using PHP.</p>
<p>Tags: <a href="http://technorati.com/tag/PHP" rel="tag">PHP</a>, <a href="http://technorati.com/tag/lighttpd" rel="tag"> lighttpd</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/system-administration/95/how-to-map-urls-with-php-and-lighttpd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP RRDTool tutorial</title>
		<link>http://www.ioncannon.net/system-administration/59/php-rrdtool-tutorial/</link>
		<comments>http://www.ioncannon.net/system-administration/59/php-rrdtool-tutorial/#comments</comments>
		<pubDate>Tue, 18 Jul 2006 22:03:47 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[system administration]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/system-administration/59/php-rrdtool-tutorial/</guid>
		<description><![CDATA[On a number of occasions I&#039;ve used RRDTool to graph network traffic and the like. A few years ago when I started using cacti I started wondering how to make the graphs myself. Creating the graphs on the command line isn&#039;t that hard once you know how to set things up and it turns out [...]]]></description>
			<content:encoded><![CDATA[<p>On a number of occasions I&#039;ve used RRDTool to graph network traffic and the like. A few years ago when I started using <a href="http://www.cacti.net/">cacti</a> I started wondering how to make the graphs myself. Creating the graphs on the command line isn&#039;t that hard once you know how to set things up and it turns out doing the same in PHP is just as easy.</p>
<p><span id="more-59"></span></p>
<p>For this tutorial I&#039;m going to assume you understand how to get RRDTool installed and working from the command line. If not you should take a look at <a href="http://oss.oetiker.ch/rrdtool/tut/rrdtutorial.en.html">this tutorial</a> (if you are in a hurry look at the &#034;A Real World Example&#034; section) or any of the <a href="http://oss.oetiker.ch/rrdtool/tut/">tutorials on this page</a>. </p>
<p><b>Setup and introduction</b></p>
<p>You need to have PHP compiled with RRDTool support to run the following PHP examples. If you compile PHP by hand then see: <a href="http://www.ioncannon.net/system-administration/25/how-to-build-the-php-rrdtool-extension-by-hand/">how to build the php rrdtool extension by hand</a>. If you are using a distribution&#039;s pre-compiled PHP binary you should be able to install a second package with RRDTool support. You can verify that your PHP install is ready to go by running this:</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span><br />
<a href="http://www.php.net/phpinfo"><span class="kw3">phpinfo</span></a><span class="br0">&#40;</span>INFO_MODULES<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>Then search for &#034;rrdtool&#034; in the output and make sure that &#034;rrdtool support&#034; is enabled.</p>
<p>While going through each of the following steps you will notice that each call takes a couple of parameters and then one parameter that is just a string of options. The string of options is exactly how it is for generating/updating/graphing RRDs from the command line. This makes for a consistent interface for the different languages that have RRDTool support.</p>
<p><b>Creating a RRD</b></p>
<p>We first need to create a database for our data. For these examples I will be creating a database that could be used for generating network graphs. This database is created for updates every 5 minutes (300 seconds), has input and output counters that store data for the average and max counts and stores enough samples for hourly, daily, monthly and yearly graphs of both average and max.</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p>&nbsp; <span class="re0">$fname</span> <span class="sy0">=</span> <span class="st0">&quot;net.rrd&quot;</span><span class="sy0">;</span></p>
<p>&nbsp; <span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span> <span class="st0">&quot;&#8211;step&quot;</span><span class="sy0">,</span> <span class="st0">&quot;300&quot;</span><span class="sy0">,</span> <span class="st0">&quot;&#8211;start&quot;</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;DS:input:COUNTER:600:U:U&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;DS:output:COUNTER:600:U:U&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:AVERAGE:0.5:1:600&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:AVERAGE:0.5:6:700&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:AVERAGE:0.5:24:775&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:AVERAGE:0.5:288:797&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:MAX:0.5:1:600&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:MAX:0.5:6:700&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:MAX:0.5:24:775&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;RRA:MAX:0.5:288:797&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; <span class="re0">$ret</span> <span class="sy0">=</span> rrd_create<span class="br0">&#40;</span><span class="re0">$fname</span><span class="sy0">,</span> <span class="re0">$opts</span><span class="sy0">,</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$opts</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> <span class="re0">$ret</span> <span class="sy0">==</span> 0 <span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$err</span> <span class="sy0">=</span> rrd_error<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="st0">&quot;Create error: <span class="es4">$err</span><span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>After running you will have a file called net.rrd in the current directory. This is your RRD and will contain all the samples for your graphs.</p>
<p>For more information on the options to rrd_create see: <a href="http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html">rrdcreate</a></p>
<p><b>Updating a RRD</b></p>
<p>The next step is to update your RRD on the frequency you set when you created it. In the case above the frequency was set to 5 minutes (300 seconds). The following script generates random input and output values as input to the update function, sleeps for 300 seconds and then loops.</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p>&nbsp; <span class="re0">$fname</span> <span class="sy0">=</span> <span class="st0">&quot;net.rrd&quot;</span><span class="sy0">;</span></p>
<p>&nbsp; <span class="re0">$total_input_traffic</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$total_output_traffic</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></p>
<p>&nbsp; <span class="kw1">while</span><span class="br0">&#40;</span><span class="kw4">true</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$total_input_traffic</span> <span class="sy0">+=</span> <a href="http://www.php.net/rand"><span class="kw3">rand</span></a><span class="br0">&#40;</span>10000<span class="sy0">,</span> 15000<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="re0">$total_output_traffic</span> <span class="sy0">+=</span> <a href="http://www.php.net/rand"><span class="kw3">rand</span></a><span class="br0">&#40;</span>10000<span class="sy0">,</span> 30000<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">echo</span> <a href="http://www.php.net/time"><span class="kw3">time</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st0">&quot;: &quot;</span> <span class="sy0">.</span> <span class="re0">$total_input_traffic</span> <span class="sy0">.</span> <span class="st0">&quot; and &quot;</span> <span class="sy0">.</span> <span class="re0">$total_output_traffic</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="re0">$ret</span> <span class="sy0">=</span> rrd_update<span class="br0">&#40;</span><span class="re0">$fname</span><span class="sy0">,</span> <span class="st0">&quot;N:<span class="es4">$total_input_traffic</span>:<span class="es4">$total_output_traffic</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> <span class="re0">$ret</span> <span class="sy0">==</span> 0 <span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="re0">$err</span> <span class="sy0">=</span> rrd_error<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">echo</span> <span class="st0">&quot;ERROR occurred: <span class="es4">$err</span><span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <a href="http://www.php.net/sleep"><span class="kw3">sleep</span></a><span class="br0">&#40;</span>300<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>Your input and output values could be pulled from anywhere here, I just wanted to have a source that would work for anyone who wanted to try the script.</p>
<p>After letting this script run for a few hours you can run the following shell script to see what type of data you have collected so far:</p>
<p>For more information on the options to rrd_update here: <a href="http://oss.oetiker.ch/rrdtool/doc/rrdupdate.en.html">rrdupdate</a></p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="co0">#!/bin/sh</span><br />
<span class="re2">END</span>=<span class="sy0">`</span><span class="kw2">date</span> +<span class="sy0">%</span>s<span class="sy0">`</span><br />
<span class="re2">START</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="re1">$END</span>-<span class="nu0">3600</span><span class="sy0">|</span><span class="kw2">bc</span><span class="sy0">`</span> <span class="co0"># over the hour</span><br />
rrdtool fetch net.rrd AVERAGE <span class="re5">&#8211;start</span> <span class="re1">$START</span> <span class="re5">&#8211;end</span> <span class="re1">$END</span></div>
</div>
<p>That should display the average sample values for the last hour.</p>
<p><b>Displaying RRD data as a graph</b></p>
<p>Now that you have data in your RRD you will want to graph it. The following code will graph the average input and output for 1 day as well as the max for that day.</p>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="kw2">&lt;?php</span></p>
<p>&nbsp; <span class="re0">$opts</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span> <span class="st0">&quot;&#8211;start&quot;</span><span class="sy0">,</span> <span class="st0">&quot;-1d&quot;</span><span class="sy0">,</span> <span class="st0">&quot;&#8211;vertical-label=B/s&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;DEF:inoctets=net.rrd:input:AVERAGE&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;DEF:outoctets=net.rrd:output:AVERAGE&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;AREA:inoctets#00FF00:In traffic&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;LINE1:outoctets#0000FF:Out traffic<span class="es1">\\</span>r&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;CDEF:inbits=inoctets,8,*&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;CDEF:outbits=outoctets,8,*&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;COMMENT:<span class="es1">\\</span>n&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:inbits:AVERAGE:Avg In traffic\: %6.2lf %Sbps&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;COMMENT: &nbsp;&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:inbits:MAX:Max In traffic\: %6.2lf %Sbps<span class="es1">\\</span>r&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:outbits:AVERAGE:Avg Out traffic\: %6.2lf %Sbps&quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;COMMENT: &quot;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;GPRINT:outbits:MAX:Max Out traffic\: %6.2lf %Sbps<span class="es1">\\</span>r&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; <span class="re0">$ret</span> <span class="sy0">=</span> rrd_graph<span class="br0">&#40;</span><span class="st0">&quot;net_1d.gif&quot;</span><span class="sy0">,</span> <span class="re0">$opts</span><span class="sy0">,</span> <a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$opts</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span> <span class="sy0">!</span><a href="http://www.php.net/is_array"><span class="kw3">is_array</span></a><span class="br0">&#40;</span><span class="re0">$ret</span><span class="br0">&#41;</span> <span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$err</span> <span class="sy0">=</span> rrd_error<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">echo</span> <span class="st0">&quot;rrd_graph() ERROR: <span class="es4">$err</span><span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span></div>
</div>
<p>You should end up with a file named net_1d.gif in your working directory that looks something like: <br/><br />
<img src="http://d28nuaxr58rcpu.cloudfront.net/rrd-php/img/net_1d.gif"/></p>
<p>You can also do weekly and monthly graphs by changing the start parameter to -1w or -1m: <br/><br />
<img src="http://d28nuaxr58rcpu.cloudfront.net/rrd-php/img/net_1w.gif"/> <br/><br />
<img src="http://d28nuaxr58rcpu.cloudfront.net/rrd-php/img/net_1m.gif"/> <br/></p>
<p>For the impatient you can download my <a href="http://d28nuaxr58rcpu.cloudfront.net/rrd-php/net.rrd">net.rrd</a> file and try the graphs for yourself.</p>
<p>See the other tutorials for more information on the options you have for graphing.</p>
<p>For more information on the options to rrd_graph see: <a href="http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html">rrdgraph</a></p>
<p>Tags: <a href="http://technorati.com/tag/php" rel="tag">php</a>, <a href="http://technorati.com/tag/rrdtool" rel="tag"> rrdtool</a>, <a href="http://technorati.com/tag/sysadmin" rel="tag"> sysadmin</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/system-administration/59/php-rrdtool-tutorial/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>How to build the PHP rrdtool extension by hand</title>
		<link>http://www.ioncannon.net/system-administration/25/how-to-build-the-php-rrdtool-extension-by-hand/</link>
		<comments>http://www.ioncannon.net/system-administration/25/how-to-build-the-php-rrdtool-extension-by-hand/#comments</comments>
		<pubDate>Tue, 09 May 2006 16:17:28 +0000</pubDate>
		<dc:creator>carson</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[system administration]]></category>

		<guid isPermaLink="false">http://www.ioncannon.net/uncategorized/25/how-to-build-the-php-rrdtool-extension-by-hand/</guid>
		<description><![CDATA[I think by now most sysadmin types know about rrdtool and the nice graphs it makes. I recently wanted to create some graphs by hand using PHP so I turned to the php-rrdtool extension. I found that it takes a little work to get it to compile but that could be because I&#039;m not constantly [...]]]></description>
			<content:encoded><![CDATA[<p>I think by now most sysadmin types know about <a href="http://oss.oetiker.ch/rrdtool/">rrdtool</a> and the nice graphs it makes. I recently wanted to create some graphs by hand using PHP so I turned to the php-rrdtool extension. I found that it takes a little work to get it to compile but that could be because I&#039;m not constantly recompiling PHP and just don&#039;t know better. You can get this module as an rpm for fedora (php-rrdtool) but I like to compile php by hand so I couldn&#039;t use it. I&#039;m going to assume that you know how to compile PHP normally with whatever other items you want to include and that you have the rrdtool development libraries installed or have compiled and installed rrdtool from source.</p>
<p><span id="more-25"></span></p>
<h3>Step 1. Get the PHP rrdtool source</h3>
<p>Go to the contrib directory on the rrdtool distribution site:<br />
<a href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/pub/contrib/">http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/pub/contrib/</a></p>
<p>There are a number of files in this directory that mention rrd. You want the one named: <a href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/pub/contrib/php_rrdtool.tgz">php_rrdtool.tgz</a> </p>
<p><a></a></p>
<h3>Step 2. Untar into the correct place</h3>
<p>Now that you have the source go into your php source directory and then into the ext directory. So you will be somewhere like this:</p>
<p>/usr/local/src/php-5.1.3/ext/</p>
<p>Now untar the source into this directory.</p>
<h3>Step 3. Recreate the php configuration file</h3>
<p>There is a warning that you will get if you do not have autoconf 2.13 installed on your system when you try to do this. It is easy enough to get this version if you have fedora so that is what I did. </p>
<p>One tricky part to this is that I had to remove the old configuration file first before the new one could be created.</p>
<ol>
<li>Change directory to your PHP source, if you are still in the ext directory just cd ..</li>
<li>Remove the existing configuration file</li>
<li>If you are using autoconf 2.13 run the following command: <br /> PHP_AUTOCONF=autoconf-2.13 ./buildconf &#8211;force<br /> If you are using whatever other autoconf you have installed just run: <br /> ./buildconf &#8211;force</li>
<li>You should now have a new configuration file that can be run with the &#8211;with-rrdtool option</li>
</ol>
<h3>Step 4. Test</h3>
<p>After compiling with rrdtool you should be able to use the phpinfo() function to list the installed extensions. If everything went right you should see rrdtool listed.</p>
<p>Tags: <a href="http://technorati.com/tag/rrdtool" rel="tag">rrdtool</a>, <a href="http://technorati.com/tag/php" rel="tag"> php</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioncannon.net/system-administration/25/how-to-build-the-php-rrdtool-extension-by-hand/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 2.748 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-07 09:30:29 -->

