<?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>jpeg &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/jpeg/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>on web development</description>
	<lastBuildDate>Tue, 13 Feb 2018 08:18:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.3</generator>
	<item>
		<title>Computer Algorithms: Lossy Image Compression with Run-Length Encoding</title>
		<link>/2012/05/03/computer-algorithms-lossy-image-compression-with-run-length-encoding/</link>
		<comments>/2012/05/03/computer-algorithms-lossy-image-compression-with-run-length-encoding/#comments</comments>
		<pubDate>Thu, 03 May 2012 20:27:06 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Coding theory]]></category>
		<category><![CDATA[Data compression]]></category>
		<category><![CDATA[data compression algorithm]]></category>
		<category><![CDATA[Graphics file formats]]></category>
		<category><![CDATA[image compression]]></category>
		<category><![CDATA[Image processing]]></category>
		<category><![CDATA[Information theory]]></category>
		<category><![CDATA[jpeg]]></category>
		<category><![CDATA[Lossless data compression]]></category>
		<category><![CDATA[lossy algorithm]]></category>
		<category><![CDATA[Lossy compression]]></category>
		<category><![CDATA[PCX]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Pixel]]></category>
		<category><![CDATA[Run-length encoding]]></category>
		<category><![CDATA[suitable algorithm]]></category>
		<category><![CDATA[Technology/Internet]]></category>

		<guid isPermaLink="false">/?p=3078</guid>
		<description><![CDATA[Introduction Run-length encoding is a data compression algorithm that helps us encode large runs of repeating items by only sending one item from the run and a counter showing how many times this item is repeated. Unfortunately this technique is useless when trying to compress natural language texts, because they don’t have long runs of &#8230; <a href="/2012/05/03/computer-algorithms-lossy-image-compression-with-run-length-encoding/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Lossy Image Compression with Run-Length Encoding</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Run-length Encoding">Computer Algorithms: Data Compression with Run-length Encoding </a></li>
<li><a href="/2012/01/16/computer-algorithms-data-compression-with-bitmaps/" rel="bookmark" title="Computer Algorithms: Data Compression with Bitmaps">Computer Algorithms: Data Compression with Bitmaps </a></li>
<li><a href="/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/" rel="bookmark" title="Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution">Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution </a></li>
<li><a href="/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Relative Encoding">Computer Algorithms: Data Compression with Relative Encoding </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p><a href="/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/" title="Computer Algorithms: Data Compression with Run-length Encoding">Run-length encoding</a> is a data compression algorithm that helps us encode large runs of repeating items by only sending one item from the run and a counter showing how many times this item is repeated. Unfortunately this technique is useless when trying to compress natural language texts, because they don’t have long runs of repeating elements. In the other hand RLE is useful when it comes to image compression, because images happen to have long runs pixels with identical color. </p>
<p>As you can see on the following picture we can compress consecutive pixels by only replacing each run with one pixel from it and a counter showing how many items it contains.</p>
<figure id="attachment_3101" style="width: 619px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/1.LosslessRLEforImages.png"><img src="/wp-content/uploads/2012/05/1.LosslessRLEforImages.png" alt="Lossless RLE for Images" title="Lossless RLE for Images" width="619" height="216" class="size-full wp-image-3101" srcset="/wp-content/uploads/2012/05/1.LosslessRLEforImages.png 619w, /wp-content/uploads/2012/05/1.LosslessRLEforImages-300x104.png 300w" sizes="(max-width: 619px) 100vw, 619px" /></a><figcaption class="wp-caption-text">Although lossless RLE can be quite effective for image compression, it is still not the best approach!</figcaption></figure>
<p>In this case we can save only counters for pixels that are repeated more than once. Such the input stream “aaaabbaba” will be compressed as “[4]a[2]baba”. </p>
<p>Actually there are several ways run-length encoding can be used for image compression. A possible way of compressing a picture can be either row by row or column by column, as it is shown on the picture below.</p>
<p><figure id="attachment_3102" style="width: 621px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/2.RowbyRowandColbyCol.png"><img src="/wp-content/uploads/2012/05/2.RowbyRowandColbyCol.png" alt="Row by row or column by column compression" title="Row by row or column by column compression" width="621" height="300" class="size-full wp-image-3102" srcset="/wp-content/uploads/2012/05/2.RowbyRowandColbyCol.png 621w, /wp-content/uploads/2012/05/2.RowbyRowandColbyCol-300x144.png 300w" sizes="(max-width: 621px) 100vw, 621px" /></a><figcaption class="wp-caption-text">Row by row or column by column compression.</figcaption></figure><span id="more-3078"></span></p>
<p>The problem in practice is that sometimes compressing row by row may be effective, while in other cases the same approach is very ineffective. This is illustrated by the image below.</p>
<figure id="attachment_3103" style="width: 621px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/3.EffectiveandIneffectiveCompression.png"><img src="/wp-content/uploads/2012/05/3.EffectiveandIneffectiveCompression.png" alt="Effective and Ineffective Compression" title="Effective and Ineffective Compression" width="621" height="328" class="size-full wp-image-3103" srcset="/wp-content/uploads/2012/05/3.EffectiveandIneffectiveCompression.png 621w, /wp-content/uploads/2012/05/3.EffectiveandIneffectiveCompression-300x158.png 300w" sizes="(max-width: 621px) 100vw, 621px" /></a><figcaption class="wp-caption-text">Sometimes image compression may be done only after some preprocessing that can help us understand the best compression approach!</figcaption></figure>
<p>Obviously run-length encoding is a very good approach when compressing images, however when we talk about big images with millions of pixels it’s somehow natural to come with some lossy compression.</p>
<h2>Overview</h2>
<p>Lossy RLE is a very suitable algorithm when it comes to images, because in most of the cases large images do appear to have big spaces of identical pixel colors, i.e. when the half of the picture is the blue sky. By using lossy compression we can skip very short runs.</p>
<p>First we’ve to say how long will be the shortest run that we will keep in the compression. For instance if 3 is the shortest run, then runs of 2 consecutive elements will be skipped.</p>
<figure id="attachment_3104" style="width: 621px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/4.LossessImageRow.png"><img src="/wp-content/uploads/2012/05/4.LossessImageRow.png" alt="Lossless Pixel Row" title="Lossless Pixel Row" width="621" height="173" class="size-full wp-image-3104" srcset="/wp-content/uploads/2012/05/4.LossessImageRow.png 621w, /wp-content/uploads/2012/05/4.LossessImageRow-300x83.png 300w" sizes="(max-width: 621px) 100vw, 621px" /></a><figcaption class="wp-caption-text">Lossless compression of a pixel row in some cases can be very inefective!</figcaption></figure>
<p>Of course if we set the shortest run to be only one element long, this will make our compression completely lossless, which isn’t very effective. However when we talk about millions of pixels even runs of three or more elements are very short, so it’s up to the developer to decide how long will be the shortest run.</p>
<h3>Some Examples</h3>
<p>Let&#8217;s first define the shortest run that we will keep untouched to be at least three element long.</p>
<figure id="attachment_3105" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/5.LossyImageRow.png"><img src="/wp-content/uploads/2012/05/5.LossyImageRow.png" alt="Lossy Pixel Row" title="Lossy Pixel Row" width="620" height="273" class="size-full wp-image-3105" srcset="/wp-content/uploads/2012/05/5.LossyImageRow.png 620w, /wp-content/uploads/2012/05/5.LossyImageRow-300x132.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">We can lose some information that is invisbile to the eye.</figcaption></figure>
<p>The above image is compressed more effectively than the lossless pixel row from the previous picture.</p>
<p>The thing is how to merge short runs. For instance the following three runs have to be blended into one color run.</p>
<figure id="attachment_3106" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/6.BlendingShortRuns.png"><img src="/wp-content/uploads/2012/05/6.BlendingShortRuns.png" alt="Blending Short Runs" title="Blending Short Runs" width="620" height="199" class="size-full wp-image-3106" srcset="/wp-content/uploads/2012/05/6.BlendingShortRuns.png 620w, /wp-content/uploads/2012/05/6.BlendingShortRuns-300x96.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">We must chose how to blend short runs!</figcaption></figure>
<p>We can choose the middle color (option #1) or not, but this will always depend on the picture and it will be effective in some cases and ineffective in other.</p>
<h2>Implementation</h2>
<p>Implementing run-length encoding is easy in general. Here’s a simple <a href="/category/php/" title="PHP on stoimen.com">PHP</a> code that shows a lossy RLE.</p>
<pre lang="PHP">
/**
 * Compresses an input list of objects by losing some data using
 * run-length encoding
 * 
 * @param mixed $objectList
 * @param int $minLength
 */
function lossyRLE($objectList, $minLength)
{
	$len 		= is_string($objectList) 
			? strlen($objectList)		// string as an input stream
			: count($objectList);		// array as an input stream
	$j 		= 1;
	$compressed = array();				// compressed output
	
	for ($i = 0; $i < $len; $i++) {
		if (isset($objectList[$i+1]) &#038;&#038; $objectList[$i] == $objectList[$i+1]) {
			$j++;
		} else {
			$l = count($compressed);
			// This is where RLE is converted to a lossy algorithm!
			// In case the run is shorter than a predefined length the
			// algorithm will skip these elements and will stretch the last
			// saved run.
			// NOTE: this logic can be changed in order to take other
			// decisions depending on the goals.
			if ($j < $minLength &#038;&#038; $j < $l) {
				$compressed[$l-1]['count'] += $j;
			} else {
				$compressed[] = array('count' => $j, $objectList[$i]);
			}
			$j = 1;
		}
	}
	
	return $compressed;
}

$input = 'aaaabbaabbbbba';

// aaaaaaaabbbbbb
lossyRLE($input, 3);
</pre>
<p>The code above can be modified in order to work with more complex data. Let’s say we have a “pixel” abstraction as on the example above.</p>
<pre lang="PHP">
/**
 * Pixel abstraction
 */
class Pixel
{
	private $_color = null;
	
	public function __construct($color = '')
	{
		$this->_color = $color;
	}
	
	public function getColor() 
	{
		return $this->_color;
	}
}

/**
 * Inits the pixels array
 * 
 * @param array $pixels
 */
function init(array &$pixels = array())
{
	$colors = array('red', 'green', 'blue');
	
	for ($i = 0; $i < 100; $i++) {
		$pixels[] = new Pixel($colors[mt_rand(0, 2)]);
	}
}

/**
 * Compresses an input list of objects by losing some data using
 * run-length encoding
 * 
 * @param mixed $objectList
 * @param int $minLength
 */
function lossyRLE($objectList, $minLength)
{
	$len 		= is_string($objectList) 
			? strlen($objectList)		// string as an input stream
			: count($objectList);		// array as an input stream
	$j 		= 1;
	$compressed = array();				// compressed output
	
	for ($i = 0; $i < $len; $i++) {
		if (isset($objectList[$i+1]) &#038;&#038; $objectList[$i] == $objectList[$i+1]) {
			$j++;
		} else {
			$l = count($compressed);
			// This is where RLE is converted to a lossy algorithm!
			// In case the run is shorter than a predefined length the
			// algorithm will skip these elements and will stretch the last
			// saved run.
			// NOTE: this logic can be changed in order to take other
			// decisions depending on the goals.
			if ($j < $minLength &#038;&#038; $l > $j) {
				$compressed[$l-1]['count'] += $j;
			} else {
				$compressed[] = array('count' => $j, $objectList[$i]);
			}
			$j = 1;
		}
	}
	
	return $compressed;
}

$pixels = array();

// initializes the pixels array
init($pixels);

$compressed = lossyRLE($pixels, 3);

print_r($compressed);
</pre>
<h2>Complexity</h2>
<p>In general lossless RLE compelxity is linear &#8211; O(n) where n is the number of items from the input stream. Even with the small modification above the complexity remains linear. However we can modify the compression in a slightly different manner (in order to get the middle value from consecutive short runs). This will somehow affect the complexity of the algorithm, of course.</p>
<h2>Application</h2>
<p>Run-length encoding isn’t a very effective option when compressing texts, but for images where long runs of the identical pixels happen to occur it is quite useful. </p>
<figure id="attachment_3107" style="width: 622px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/7.LossyRLE.png"><img src="/wp-content/uploads/2012/05/7.LossyRLE.png" alt="Lossy RLE in Practice" title="Lossy RLE in Practice" width="622" height="483" class="size-full wp-image-3107" srcset="/wp-content/uploads/2012/05/7.LossyRLE.png 622w, /wp-content/uploads/2012/05/7.LossyRLE-300x232.png 300w" sizes="(max-width: 622px) 100vw, 622px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<p>Nevertheless RLE is easy to convert into a lossy algorithm, that makes it very suitable for image compression.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Run-length Encoding">Computer Algorithms: Data Compression with Run-length Encoding </a></li>
<li><a href="/2012/01/16/computer-algorithms-data-compression-with-bitmaps/" rel="bookmark" title="Computer Algorithms: Data Compression with Bitmaps">Computer Algorithms: Data Compression with Bitmaps </a></li>
<li><a href="/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/" rel="bookmark" title="Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution">Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution </a></li>
<li><a href="/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Relative Encoding">Computer Algorithms: Data Compression with Relative Encoding </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/05/03/computer-algorithms-lossy-image-compression-with-run-length-encoding/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>PHP Strings: How to Get the Extension of a File</title>
		<link>/2011/07/29/php-strings-how-to-get-the-extension-of-a-file/</link>
		<comments>/2011/07/29/php-strings-how-to-get-the-extension-of-a-file/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 06:25:32 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[micro tutorial]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[Computer file formats]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[elegant solution]]></category>
		<category><![CDATA[EXE]]></category>
		<category><![CDATA[Filename]]></category>
		<category><![CDATA[gif]]></category>
		<category><![CDATA[jpeg]]></category>
		<category><![CDATA[path]]></category>

		<guid isPermaLink="false">/?p=2335</guid>
		<description><![CDATA[EXE or GIF or DLL or &#8230; Most of the code chunks I&#8217;ve seen about getting a file extension from a string are based on some sort of string manipulation. $filename = '/my/path/image.jpeg'; echo substr($filename, strrpos($filename, '.') + 1); Howerver there is a more elegant solution. $filename = '/my/path/image.jpeg'; echo strtolower(pathinfo($filename, PATHINFO_EXTENSION)); Thus you rely &#8230; <a href="/2011/07/29/php-strings-how-to-get-the-extension-of-a-file/" class="more-link">Continue reading <span class="screen-reader-text">PHP Strings: How to Get the Extension of a File</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/04/26/php-strings-dont-need-quotes/" rel="bookmark" title="PHP Strings Don&#8217;t Need Quotes">PHP Strings Don&#8217;t Need Quotes </a></li>
<li><a href="/2010/05/25/download-files-with-zend-framework/" rel="bookmark" title="Download Files with Zend Framework">Download Files with Zend Framework </a></li>
<li><a href="/2011/08/18/powerful-php-less-known-string-manipulation/" rel="bookmark" title="Powerful PHP: Less Known String Manipulation">Powerful PHP: Less Known String Manipulation </a></li>
<li><a href="/2010/10/04/some-php-tips-basename/" rel="bookmark" title="Some PHP Tips: basename()">Some PHP Tips: basename() </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>EXE or GIF or DLL or &#8230;</h2>
<p>Most of the code chunks I&#8217;ve seen about getting a file extension from a string are based on some sort of string manipulation.<br />
<figure id="attachment_2351" style="width: 235px" class="wp-caption aligncenter"><a href="/wp-content/uploads/2011/07/filename_extension.jpg"><img class="size-full wp-image-2351" title="filename_extension" src="/wp-content/uploads/2011/07/filename_extension.jpg" alt="Get the Filename Extension with PHP" width="235" height="235" srcset="/wp-content/uploads/2011/07/filename_extension.jpg 235w, /wp-content/uploads/2011/07/filename_extension-150x150.jpg 150w" sizes="(max-width: 235px) 100vw, 235px" /></a><figcaption class="wp-caption-text">If you want to get the filename extension with PHP is better to use pathinfo() than string manipulations</figcaption></figure></p>
<pre lang="php">$filename = '/my/path/image.jpeg';
echo substr($filename, strrpos($filename, '.') + 1);</pre>
<p>Howerver there is a more elegant solution.</p>
<pre lang="php">$filename = '/my/path/image.jpeg';
echo strtolower(pathinfo($filename, PATHINFO_EXTENSION));</pre>
<p>Thus you rely on PHP built in functions and it&#8217;s harder to overlook the exact string manipulation approach.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/04/26/php-strings-dont-need-quotes/" rel="bookmark" title="PHP Strings Don&#8217;t Need Quotes">PHP Strings Don&#8217;t Need Quotes </a></li>
<li><a href="/2010/05/25/download-files-with-zend-framework/" rel="bookmark" title="Download Files with Zend Framework">Download Files with Zend Framework </a></li>
<li><a href="/2011/08/18/powerful-php-less-known-string-manipulation/" rel="bookmark" title="Powerful PHP: Less Known String Manipulation">Powerful PHP: Less Known String Manipulation </a></li>
<li><a href="/2010/10/04/some-php-tips-basename/" rel="bookmark" title="Some PHP Tips: basename()">Some PHP Tips: basename() </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2011/07/29/php-strings-how-to-get-the-extension-of-a-file/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Reading GPS Latitude and Longitude from Image and Video Files</title>
		<link>/2011/02/04/reading-gps-latitude-and-longitude-from-image-and-video-files/</link>
		<comments>/2011/02/04/reading-gps-latitude-and-longitude-from-image-and-video-files/#comments</comments>
		<pubDate>Fri, 04 Feb 2011 10:16:14 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[micro tutorial]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Apple Inc.]]></category>
		<category><![CDATA[Application software]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Container formats]]></category>
		<category><![CDATA[Digital photography]]></category>
		<category><![CDATA[Exchangeable image file format]]></category>
		<category><![CDATA[ExifTool]]></category>
		<category><![CDATA[Geotagging]]></category>
		<category><![CDATA[GPS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[jpeg]]></category>
		<category><![CDATA[Metadata]]></category>
		<category><![CDATA[mobile device]]></category>
		<category><![CDATA[Mobile Devices]]></category>
		<category><![CDATA[MPEG-4]]></category>
		<category><![CDATA[navigation software]]></category>
		<category><![CDATA[Nokia E71 Smartphone]]></category>
		<category><![CDATA[QuickTime]]></category>
		<category><![CDATA[Resolution Unit]]></category>
		<category><![CDATA[Smartphones]]></category>
		<category><![CDATA[Symbian]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[web platform]]></category>

		<guid isPermaLink="false">/?p=2153</guid>
		<description><![CDATA[The State of GPS Data from Mobile Devices Most of the mobile devices today support GPS geo tagging. In fact most of them come bundled with navigation software that uses GPS and therefore all the pictures and (maybe) videos can be geo tagged. But as expected different vendors come with different support and formats. iPhone &#8230; <a href="/2011/02/04/reading-gps-latitude-and-longitude-from-image-and-video-files/" class="more-link">Continue reading <span class="screen-reader-text">Reading GPS Latitude and Longitude from Image and Video Files</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2011/01/27/few-thoughts-on-web-video/" rel="bookmark" title="Few Thoughts on Web Video">Few Thoughts on Web Video </a></li>
<li><a href="/2010/03/05/video-sites-must-use-mp4-and-only-mp4/" rel="bookmark" title="Video sites must use &#8230; mp4 and only mp4!">Video sites must use &#8230; mp4 and only mp4! </a></li>
<li><a href="/2010/05/25/download-files-with-zend-framework/" rel="bookmark" title="Download Files with Zend Framework">Download Files with Zend Framework </a></li>
<li><a href="/2010/05/21/check-youtube-video-existence-with-zend_gdata_youtube/" rel="bookmark" title="Check YouTube Video Existence with Zend_Gdata_YouTube">Check YouTube Video Existence with Zend_Gdata_YouTube </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>The State of GPS Data from Mobile Devices</h2>
<p>Most of the mobile devices today support GPS geo tagging. In fact most of them come bundled with navigation software that uses GPS and therefore all the pictures and (maybe) videos can be geo tagged. But as expected different vendors come with different support and formats.<br />
<br clear="all" /><a href="/wp-content/uploads/2011/02/iphone.png"><img class="alignleft size-full wp-image-2162" title="iphone" src="/wp-content/uploads/2011/02/iphone.png" alt="" width="120" height="78" /></a><br />
<br clear="all" /></p>
<p><a title="iPhone OS" href="http://en.wikipedia.org/wiki/IOS_%28Apple%29" target="_blank">iPhone OS</a> comes with geotagging both on video and image files, while the latest <a title="Android" href="http://www.android.com/" target="_blank">Android</a> and <a title="Symbian" href="http://blog.symbian.org/" target="_blank">Symbian</a> (the Nokia main OS for smartphones) can geo tag only images.</p>
<p>Even more &#8211; until recently Symbian didn&#8217;t support any geotagging before the installation of an additional software &#8211; such as <a title="Location Tagger" href="http://betalabs.nokia.com/apps/location-tagger" target="_blank">Location Tagger</a> . So generally the things are quite simple:</p>
<ol>
<li>iPhone OS geotags both video and image files;</li>
<li>Android geotags only images;</li>
<li>Symbian geotags only images &#8211; and on some devices this is possible only after installing a software;</li>
</ol>
<p>This is in breve the state of mobile device geotagging!<span id="more-2153"></span></p>
<h2>Why Use GPS Data?</h2>
<p>Perhaps one of the main reasons why not support geotagging especially on video files can be the usage of those geo tags. First of all what a geotag means?<br />
<br clear="all" /><br />
<a href="/wp-content/uploads/2011/02/android.png"><img class="alignleft size-full wp-image-2165" title="android" src="/wp-content/uploads/2011/02/android.png" alt="Android Logo" width="150" height="150" /></a><br />
<br clear="all" /><br />
You may know that even Android doesn&#8217;t &#8220;geotag&#8221; videos this is not quite true. Because after using you gallery you can see where those videos are shot. This is fantastic, but actually the real information about where the video has been taken is not into the video file, but it&#8217;s in an additional log file that keeps it. Thus actually the video files doesn&#8217;t know the geo coordinates.</p>
<p>Here comes the problem with video format, because you cannot be sure that every format supports tags that can keep geo coordinates. Actually quicktime&#8217;s MOV can store them, while Symbian&#8217;s 3GP cannot. In fact Symbian cannot store any geo information about video files!</p>
<p>So now we&#8217;ve at least three different formats for each of those three vendors.</p>
<ol>
<li>quicktime for iPhone</li>
<li>mpeg-4 with Android</li>
<li>3gp with Symbian</li>
</ol>
<p>For now I can only say that iPhone can keep the geotag into his video files.<br />
<br clear="all" /><br />
<a href="/wp-content/uploads/2011/02/symbian.png"><img class="alignleft size-full wp-image-2164" title="symbian" src="/wp-content/uploads/2011/02/symbian.png" alt="Symbian Logo" width="200" height="55" /></a><br />
<br clear="all" /><br />
But let me return to the question &#8211; why we need this geo tags? Until the video file is on the mobile device &#8211; there&#8217;s no problem. But once you try to download it &#8211; whether on <a title="Flickr" href="http://www.flickr.com/" target="_blank">Flickr</a>, <a title="YouTube" href="http://youtube.com/" target="_blank">YouTube</a>, <a title="Picasa Web Albums" href="https://picasaweb.google.com/" target="_blank">Picasa</a>, etc. you&#8217;ll lose any geo information if it&#8217;s not into the file tags. And of course if the above sites can&#8217;t read it!</p>
<p>The general reason to store this data into the file is to move it along with the file. Once you move this file from your mobile device to a web platform you&#8217;ll see where the file has been created.</p>
<h2>EXIF, Exiftool and PHP&#8217;s exif_read_data</h2>
<p>There are several tools to read geotags. For images, and here we talk only for JPEGs, this is the <a title="EXIF" href="http://www.exif.org/" target="_blank">EXIF</a> information. You can download the exif command line program and try to reed data with it:</p>
<pre lang="bash">
exif filename.jpg
</pre>
<p>Which can result in something like that:</p>
<pre lang="bash">
Manufacturer        |Nokia                                                     
Model               |E71                                                       
Orientation         |top - left                                                
x-Resolution        |300.00                                                    
y-Resolution        |300.00                                                    
Resolution Unit     |Inch                                                      
YCbCr Positioning   |centered                                                  
Compression         |JPEG compression                                          
x-Resolution        |72.00                                                     
y-Resolution        |72.00                                                     
Resolution Unit     |Inch                                                      
FNumber             |f/3.2                                                     
Exif Version        |Exif Version 2.2                                          
Date and Time (origi|2011:01:24 12:15:01                                       
Date and Time (digit|2011:01:24 12:15:01                                       
ComponentsConfigurat|Y Cb Cr -                                                 
Aperture            |3.20 EV (f/3.0)                                           
Light Source        |0                                                         
Flash               |Flash did not fire, auto mode.                            
Focal Length        |4.9 mm                                                    
FlashPixVersion     |FlashPix Version 1.0                                      
Color Space         |sRGB                                                      
PixelXDimension     |2048                                                      
PixelYDimension     |1536                                                      
Custom Rendered     |Normal process                                            
Exposure Mode       |Auto exposure                                             
White Balance       |Auto white balance                                        
Digital Zoom Ratio  |1.00                                                      
Scene Capture Type  |Standard                                                  
GPS tag version     |0x02, 0x02, 0x00, 0x00                                    
North or South Latit|N                                                         
Latitude            |42.00, 39.00, 24.67                                       
East or West Longitu|E                                                         
Longitude           |23.00, 21.00, 28.45                                       
Altitude reference  |0x00                                                      
Altitude            |625.50 
</pre>
<p>While for video files (iPhone) exif cannot help you, this is possible through <a title="Exiftool" href="http://www.sno.phy.queensu.ca/~phil/exiftool/" target="_blank">Exiftool</a>. With it you can read even iPhone video geotags:</p>
<pre lang="bash">
./exiftool filname.mov
</pre>
<p>In addition this information can be read with PHP via <a title="read_exif_data" href="http://php.net/manual/en/function.read-exif-data.php" target="_blank">exif_read_data</a>:</p>
<pre lang="php">
$info = exif_read_data('filename.jpg');
var_dump($info);
</pre>
<p>And this will give you not only standard tags, but geo tags too.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2011/01/27/few-thoughts-on-web-video/" rel="bookmark" title="Few Thoughts on Web Video">Few Thoughts on Web Video </a></li>
<li><a href="/2010/03/05/video-sites-must-use-mp4-and-only-mp4/" rel="bookmark" title="Video sites must use &#8230; mp4 and only mp4!">Video sites must use &#8230; mp4 and only mp4! </a></li>
<li><a href="/2010/05/25/download-files-with-zend-framework/" rel="bookmark" title="Download Files with Zend Framework">Download Files with Zend Framework </a></li>
<li><a href="/2010/05/21/check-youtube-video-existence-with-zend_gdata_youtube/" rel="bookmark" title="Check YouTube Video Existence with Zend_Gdata_YouTube">Check YouTube Video Existence with Zend_Gdata_YouTube </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2011/02/04/reading-gps-latitude-and-longitude-from-image-and-video-files/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Download Files with Zend Framework</title>
		<link>/2010/05/25/download-files-with-zend-framework/</link>
		<comments>/2010/05/25/download-files-with-zend-framework/#comments</comments>
		<pubDate>Tue, 25 May 2010 14:06:13 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[micro tutorial]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[Computer file formats]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Graphics file formats]]></category>
		<category><![CDATA[jpeg]]></category>
		<category><![CDATA[PHP programming language]]></category>
		<category><![CDATA[Social Issues]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[Web application frameworks]]></category>

		<guid isPermaLink="false">/?p=1571</guid>
		<description><![CDATA[Download a File The title may sound unclear enough, but the task is simple. You&#8217;ve to make a file download process within a Zend Framework&#8217;s controller. Let&#8217;s assume we&#8217;ve the DownloadController setup:<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2010/07/21/setting-up-global-cache-in-zend-framework/" rel="bookmark" title="Setting Up Global Cache in Zend Framework">Setting Up Global Cache in Zend Framework </a></li>
<li><a href="/2010/08/09/models-in-zend-framework-initialize-all-methods-with-init/" rel="bookmark" title="Models in Zend Framework &#8211; Initialize All Methods with init()">Models in Zend Framework &#8211; Initialize All Methods with init() </a></li>
<li><a href="/2010/04/07/upload-a-file-with-zend-framework/" rel="bookmark" title="Upload a File with Zend Framework">Upload a File with Zend Framework </a></li>
<li><a href="/2011/01/18/download-images-with-php/" rel="bookmark" title="Download Images with PHP">Download Images with PHP </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Download a File</h2>
<p>The title may sound unclear enough, but the task is simple. You&#8217;ve to make a file download process within a Zend Framework&#8217;s controller. Let&#8217;s assume we&#8217;ve the DownloadController setup:</p>
<pre lang="php">
<?php

class DownloadController extends Zend_Controller_Action
{
	public function indexAction()
	{}	
}
</pre>
<p>In PHP there are at least three simple lines of code that will do the job of downloading a file.</p>
<pre lang="php">
header('Content-Type: image/jpeg');
header('Content-Disposition: attachment; filename="logo.jpg"');
readfile('images/logo.jpg');
</pre>
<p>Note that here there is a content-type header, which is important cause the browsers understands what kind of file is supposed to be downloaded. The second line suggests a name of the downloaded file and the third one returns the file to the client.</p>
<h2>Download a File ... within Zend Framework</h2>
<p>Those three lines wont work alone in a ZF application, because there's no view, but even if you create a .phtml (view) file for this action it won't work, because the header of the returned file is modified.</p>
<p>The question is how to possibly return the file for download, perhaps write some statistics to the database and if there's a problem (some permission issues for instance) return a message to the user.</p>
<h2>The Basic Solution</h2>
<p>The solution is simple. First make it work by disabling the view and possibly the layout for this action:</p>
<pre lang="php">
public function indexAction()
{
	header('Content-Type: image/jpeg');
	header('Content-Disposition: attachment; filename="logo.jpg"');
	readfile('images/logo.jpg');
	
	// disable the view ... and perhaps the layout
	$this->view->layout()->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);
}
</pre>
<p>Than add some code where you can check the permissions. Just because there's no view for this action you can redirect to another - errorAction():</p>
<pre lang="php">
public function indexAction()
{
    if (userHasNoPermissions) {
        $this->view->msg = 'This file cannot be downloaded!';
        $this->_forward('error', 'download');
    }

    header('Content-Type: image/jpeg');
    header('Content-Disposition: attachment; filename="logo.jpg"');
    readfile('images/logo.jpg');

    // disable layout and view
    $this->view->layout()->disableLayout();
    $this->_helper->viewRenderer->setNoRender(true);
}
</pre>
<p>But that still will prompt you a file to download, so there should be a return statement that will return false:</p>
<pre lang="php">
public function indexAction()
{
    if (userHasNoPermissions) {
        $this->view->msg = 'This file cannot be downloaded!';
        $this->_forward('error', 'download');
        return FALSE;
    }

    header('Content-Type: image/jpeg');
    header('Content-Disposition: attachment; filename="logo.jpg"');
    readfile('images/logo.jpg');

    // disable layout and view
    $this->view->layout()->disableLayout();
    $this->_helper->viewRenderer->setNoRender(true);
}
</pre>
<p>So here's the complete source of DownloadController.php:</p>
<pre lang="php">
<?php

class DownloadController extends Zend_Controller_Action
{
	public function indexAction()
	{
	    if (userHasNoPermissions) {
	        $this->view->msg = 'This file cannot be downloaded!';
	        $this->_forward('error', 'download');
	        return FALSE;
	    }
	
	    header('Content-Type: image/jpeg');
	    header('Content-Disposition: attachment; filename="logo.jpg"');
	    readfile('images/logo.jpg');
	
	    // disable layout and view
	    $this->view->layout()->disableLayout();
	    $this->_helper->viewRenderer->setNoRender(true);
	}	
	
	public function errorAction()
	{}
}
</pre>
<p>and the error.phtml:</p>
<pre lang="php">
<?php echo $this->msg ?>
</pre>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2010/07/21/setting-up-global-cache-in-zend-framework/" rel="bookmark" title="Setting Up Global Cache in Zend Framework">Setting Up Global Cache in Zend Framework </a></li>
<li><a href="/2010/08/09/models-in-zend-framework-initialize-all-methods-with-init/" rel="bookmark" title="Models in Zend Framework &#8211; Initialize All Methods with init()">Models in Zend Framework &#8211; Initialize All Methods with init() </a></li>
<li><a href="/2010/04/07/upload-a-file-with-zend-framework/" rel="bookmark" title="Upload a File with Zend Framework">Upload a File with Zend Framework </a></li>
<li><a href="/2011/01/18/download-images-with-php/" rel="bookmark" title="Download Images with PHP">Download Images with PHP </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2010/05/25/download-files-with-zend-framework/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Optimize your images &#8211; improve the performance</title>
		<link>/2009/04/07/optimize-your-images-improve-the-performance/</link>
		<comments>/2009/04/07/optimize-your-images-improve-the-performance/#respond</comments>
		<pubDate>Tue, 07 Apr 2009 05:39:19 +0000</pubDate>
		<dc:creator><![CDATA[stoimen]]></dc:creator>
				<category><![CDATA[featured]]></category>
		<category><![CDATA[micro tutorial]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[alphaimageloader]]></category>
		<category><![CDATA[baseline]]></category>
		<category><![CDATA[gif]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[jpeg]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[png32]]></category>
		<category><![CDATA[png8]]></category>
		<category><![CDATA[progressive]]></category>
		<category><![CDATA[transparency]]></category>

		<guid isPermaLink="false">/?p=473</guid>
		<description><![CDATA[Learn the differences between image formats<div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2009/04/23/when-you-should-use-base64-for-images/" rel="bookmark" title="When you should use base64 for images">When you should use base64 for images </a></li>
<li><a href="/2010/01/13/optimizing-the-web-start-with-the-images/" rel="bookmark" title="Optimizing the web. Start with the images!">Optimizing the web. Start with the images! </a></li>
<li><a href="/2010/07/01/replace-the-broken-images-with-a-default-image-with-javascript/" rel="bookmark" title="Replace the Broken Images with a Default Image with JavaScript">Replace the Broken Images with a Default Image with JavaScript </a></li>
<li><a href="/2011/07/29/php-strings-how-to-get-the-extension-of-a-file/" rel="bookmark" title="PHP Strings: How to Get the Extension of a File">PHP Strings: How to Get the Extension of a File </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Overview</h2>
<p>In a series of articles I&#8217;ll share what&#8217;s my experience with image optimization. Of course the most images you have the most page weight you have. That&#8217;s why optimizing your images should be your primary task.</p>
<h2>Image Formats</h2>
<p>First, I&#8217;m gonna mention several formats, which everyone of the webdevs are using widely. There are GIF, JPEG and PNG, where PNG can be either PNG8 and PNG24 (PNG32 is also available as name of that format).</p>
<p>What are the differences between them and when to use one or another?</p>
<p>Well some of us just use one or another even without knowing the difference or without thinking about the optimization. I remember when I just put the images in JPEG with no idea what are the other formats before.</p>
<p>In fact all the formats has pros and cons.</p>
<h2>JPEG</h2>
<p>The JPEG format can be either progressive or baseline. The difference is that the progressive JPEG can be loaded directly in the browser with very low quality and then to load with better quality. Some experts insist that this is old school, but I don&#8217;t think so. When the image is not the required one (think of a wallpaper preview) the user can skip and go to another without waiting the hole image. The baseline JPEG is loading the good quality image but starting from top to bottom. With portions of the image.</p>
<h3>IE and progressive JPEGs</h3>
<p>Of course the Internet Explorer 6 don&#8217;t support the progressive downloading of an JPEG even if it&#8217;s progressive. Well this is no issue till the IE loads the image like a baseline JPEG.</p>
<h3>Which JPEG is progressive and which is baseline</h3>
<p>You can certainly make some test to determine which JPEG is progressive and which is baseline, from the loading behaviour in your browser. If you&#8217;d like to convert an image to a progressive JPEG or baseline you can use a free open source programs out there in the wild online space. Once they are converted to one or another format you can use them widely. Because most of the tools are comand line open source tools you can automate them on the server where the user uploads it&#8217;s images. Now every big image can be converted to be progressive.</p>
<h3>When to use progressive and baseline JPEGs?</h3>
<p>Well the tests show that for images small than 10 K best compression you get with baseline, and for bigger images the small size you get is with progressive JPEGs. There&#8217;s the rule use the baseline for thumbs and progressive for any other big image.</p>
<h2>GIF</h2>
<p>This format is well known from the early ages of the web. It allows transparency and animation. Actually the problem with the GIF images is that they don&#8217;t support semi-transparency which is a problem nowadays. Today the web users are used to good quality images and somehow the GIF is not suitable. But it&#8217;s still the most used format for icons and of course animations.</p>
<h3>When should I use GIF?</h3>
<p>Well as I&#8217;ll mention in a while the PNG8 is a better format than GIF for transparent small icons. But if you should use some kind of an animation like ajax loading circle (or bar) the GIF format is suitable for you. Than you must use a GIF.</p>
<h2>PNG</h2>
<p>As I said PNG can be either PNG8 or PNG24 (which is also called PNG32). Actually PNG8 acts just like GIF, with the important exception that it supports semi-transparency, but yet again on every browser except IE6. In IE6 the PNG8 is just the same like GIF which is not so bad. If you&#8217;d like to use GIF for an icon, you should make it PNG8. There are semi-transparent pixels (except IE6 and above) and you get better experience on other browsers than GIF.</p>
<h3>PNG32 transparency?</h3>
<p>In fact PNG32 is not transparent on IE6 (on transparent pixels IE puts some kind of gray pixels). There you can use AlphaImageLoader filter, but that can dramaticaly slow down your browser, so it&#8217;s not a good idea.</p>
<p>You should avoid the PNG32 transparent images and the usage of AlphaImageLoader filter.</p>
<h2>Conclusion</h2>
<p>For every of these formats there lots of tools that remove system information from the image crash and crunch the files so that they become smaller. They can be automated and used on the server.</p>
<p>Now when you use different formats you can be aware of the differences between them and to use the appropriate ones.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2009/04/23/when-you-should-use-base64-for-images/" rel="bookmark" title="When you should use base64 for images">When you should use base64 for images </a></li>
<li><a href="/2010/01/13/optimizing-the-web-start-with-the-images/" rel="bookmark" title="Optimizing the web. Start with the images!">Optimizing the web. Start with the images! </a></li>
<li><a href="/2010/07/01/replace-the-broken-images-with-a-default-image-with-javascript/" rel="bookmark" title="Replace the Broken Images with a Default Image with JavaScript">Replace the Broken Images with a Default Image with JavaScript </a></li>
<li><a href="/2011/07/29/php-strings-how-to-get-the-extension-of-a-file/" rel="bookmark" title="PHP Strings: How to Get the Extension of a File">PHP Strings: How to Get the Extension of a File </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2009/04/07/optimize-your-images-improve-the-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
