<?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>MikeRandrup &#187; projects</title>
	<atom:link href="http://blog.MikeRandrup.com/category/projects/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.MikeRandrup.com</link>
	<description>The blog of Mike (such as it is).</description>
	<lastBuildDate>Thu, 01 Dec 2011 00:56:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>3D Land &amp; Water Coding Experiment</title>
		<link>http://blog.MikeRandrup.com/2011/11/3d-land-water-coding-experiment/</link>
		<comments>http://blog.MikeRandrup.com/2011/11/3d-land-water-coding-experiment/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 17:35:18 +0000</pubDate>
		<dc:creator>mikerandrup</dc:creator>
				<category><![CDATA[ideas]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Actionscript 3]]></category>
		<category><![CDATA[Adobe Flash]]></category>
		<category><![CDATA[After Effects CS5]]></category>
		<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Lightwave 3D]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.MikeRandrup.com/?p=539</guid>
		<description><![CDATA[Have you ever played the video game called From Dust? It contains intriguing land, water, and lava simulation. Since first playing it, I have been fascinated with the results of Ubisoft&#8217;s very interesting simulation system. I developed an inspired guess as to how the basic algorithm and technique might work. During some holiday downtime, I]]></description>
			<content:encoded><![CDATA[<p>Have you ever played the video game called From Dust?  It contains intriguing land, water, and lava simulation.  Since first playing it, I have been fascinated with the results of Ubisoft&#8217;s very interesting simulation system.  I developed an inspired guess as to how the basic algorithm and technique might work.  During some holiday downtime, I put code to the concept and came up with the following:</p>
<p><iframe width="600" height="450" src="http://www.youtube.com/embed/QUKnzkeWxOI?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>The algorithm steps through a pair of 2 Dimensional arrays containing the height of land and water at each coordinate in the grid.  During each step, it determines if and where the water would run downhill, then adjusts the old and new values accordingly.  The resolution of the grid was limited by the performance of Flash, which I could no doubt have improved dramatically by using more advanced stage drawing techniques.  After running and adjusting the simulations in Flash, I switched the movie to export a JPG image of each frame.  That sequence was then run through After Effects (frame blend) to smooth the adjustments.  The final sequences were then applied as separate Y-axis displacement maps on &#8220;land&#8221; and &#8220;water&#8221; objects in Lightwave 3D.</p>
<p>In the first of the two animations (mountain springs running downhill into a valley), a trio of simple &#8220;water emitters&#8221; put out a finite amount of water at the tops of the hills, and the algorithm runs it downhill to pool at the bottom.  The land was generated with high values at the edges, and low values at the center, with a touch of randomization of the terrain (a &#8220;valley&#8221;).</p>
<p>In the second (sea mountain rising), a flat land mass with water sitting on top (an &#8220;ocean&#8221;) is affected by a strong &#8220;land emitter&#8221; which pushes a mountain out of the sea floor.  The water is reacting by being displaced downhill from the land.  The circular wave of water was the natural product of the algorithm I created, which seems to indicate being on the right track for how the video game works internally.</p>
<p>Why generate the frames in Flash AS3?  Frankly, that choice was due to my own limitations as a programmer.  Also, my algorithm fails to ever resolve the water to a natural state of a flat surface.</p>
<p>I now have an even greater sense of awe for what the Ubisoft team achieved with their amazing video game.  For example, the game contains dynamic water foam textures which give realistic cues to how the water runs downhill and around obstacles.</p>
<p>The Flash AS3 source code is below.  I realize my coding techniques are horrible, and not even object oriented.  Had this been for anything other than a proof-of-concept fun project, many loose ends would be wrapped up.  There was nothing else in the Flash movie, as it creates all needed movieclips dynamically.  If you want to try it, just create a new Flash (ActionScript v3) document and paste the below into the frame 1 actions.  It reflects the coding for the &#8220;mountain rising out of the sea&#8221; effect.</p>
<pre>
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.geom.Matrix;
//import com.adobe.images.JPGEncoder; // external library used for saving frames

stop();
var frameNum:int = 99;

var resX:int = 40;
var resY:int = resX;

var paintStrength:Number = 1;

var tileSpacing:int = 0;
var tileWidth:int = stage.stageWidth/(resX+(resX*tileSpacing));
var tileHeight:int = stage.stageHeight/(resY+(resY*tileSpacing));

var alreadyEmitted:Number = 0;
var maxEmitted:Number = 0;

var edgeValue:Number =  0;
var maxBoundary:int = resX-1;
var drawValue:Number = paintStrength;
var editMode:String = "water";
var hideLand:Boolean = false;
var hideWater:Boolean = false;

var waterInit:Number = 0.1;
var landInit:Number = 0.05;

var updateTimer:Timer = new Timer(250);
updateTimer.addEventListener(TimerEvent.TIMER, advanceFrame);
updateTimer.start();

// used to capture frames in non-realtime
//stage.addEventListener(KeyboardEvent.KEY_DOWN, advanceFrame);

function advanceFrame(e:TimerEvent):void{
	updateMap(null)//commands
}

var parent_mc:MovieClip = new MovieClip();
stage.addChild(parent_mc);

var landMap:Array = new Array();
var landHeight:Number = 0;
landMap.push(new Array());
for (var yInit:int=0; yInit&lt;resY; yInit++) {
	var newRow:Array = new Array();
	//newRow.splice(0,newRow.length);
	newRow[0] = new Array();
	for (var xInit:int=0; xInit&lt;resX; xInit++) {
		landHeight = landInit;//+(Math.random()*.1);
		newRow[0].push(landHeight);
	}
	landMap[0].push(newRow);
}

var waterMap:Array = new Array();
waterMap.push(new Array());
for (yInit=0; yInit&lt;resY; yInit++) {
	var waterRow:Array = new Array();
	//newRow.splice(0,newRow.length);
	waterRow[0] = new Array();
	for (xInit=0; xInit&lt;resX; xInit++) {
		waterRow[0].push(waterInit);
	}
	waterMap[0].push(waterRow);
}

function calculate_new(x:int, y:int):void {
	var newVal:Number = 0;
	var newDelta:Number = 0;
	var proposedX:int = 0;
	var proposedY:int = 0;

	var minLevel:Number = 100;
	var minX:int = 0;
	var minY:int = 0;

	var curLand:Number;
	var curWater:Number;
	var checkLand:Number;
	var checkWater:Number;

	curLand = landMap[0][y][0][x];
	curWater = waterMap[0][y][0][x];
	for ( var neighborX:int=-1; neighborX&lt;=1; neighborX++) {
		for ( var neighborY:int=-1; neighborY&lt;=1; neighborY++) {

			proposedX = x+neighborX;
			proposedY = y+neighborY;
			if (
				(proposedX&lt;0) || (proposedY&lt;0) ||
				(proposedX&gt;maxBoundary) || (proposedY&gt;maxBoundary)
			) {
				//trace('skipping edge');
			}
			else {
				checkLand = landMap[0][proposedY][0][proposedX];
				checkWater = waterMap[0][proposedY][0][proposedX];
				if (neighborX==0 &#038;&#038; neighborY==0) {
					//trace('skipping self');
				}
				else {
					if ((checkLand+checkWater)&lt;minLevel) {
						minLevel = checkLand+checkWater;
						minX = proposedX;
						minY = proposedY;
						//trace('new tallness found: ' + minLevel);
					}
				}
			}
		}
	}
	compare_cells(x, y, minX, minY);
}

function compare_cells(curX:int, curY:int, checkX:int, checkY:int):void {
	var delta:Number;
	var curLand:Number = landMap[0][curY][0][curX];
	var curWater:Number = waterMap[0][curY][0][curX];
	var checkLand:Number = landMap[0][checkY][0][checkX];
	var checkWater:Number = waterMap[0][checkY][0][checkX];
	var idealLevel:Number = 0;

	// if there is water here
	if (curWater &gt; 0) {
		//if this water should fall
		if ((curLand+curLand) &gt; (checkLand+checkWater) ) { 

			// get the goal average height between the two including water
			idealLevel = (curLand + curWater + checkLand + checkWater)/2;
			if (idealLevel &gt; curLand) { idealLevel = curLand};

			delta = curLand + curWater - idealLevel;
			delta *= 0.3;
			waterMap[0][curY][0][curX] -= delta;
			waterMap[0][checkY][0][checkX] += delta;
		}
	}
}

function updateMap(eventObject:MouseEvent):void {
	frameNum++;

	// clean up stage from last update
    if(parent_mc.numChildren!=0){
        var cond:int = parent_mc.numChildren;
        while( cond -- ) {
            parent_mc.removeChildAt( cond );
        }
    }

	var shading:Number = 0;
	for (var k in waterMap[0]) {
		for (var i in waterMap[0][k][0]) {
			var square:Shape = new Shape();
			var squareMC:MovieClip = new MovieClip();
			calculate_new(i,k);

			if (waterMap[0][k][0][i]&gt;0.001 ) { // water is on this spot
				shading = get_water_color(k,i);
			}
			else { // land is showing on this spot
				shading = get_land_color(k,i);
			}

			square.graphics.beginFill(shading);
			square.graphics.drawRect(0, 0, tileWidth, tileHeight);
			square.graphics.endFill();

			squareMC.addChild(square);
			squareMC.x = (i * (tileWidth + tileSpacing + tileSpacing)) + tileSpacing;
			squareMC.y = (k * (tileHeight + tileSpacing + tileSpacing)) + tileSpacing;

			parent_mc.addChild(squareMC);
		}
	}

	//save_screenshot();  // used to capture frames in non-realtime

	// water emmitters
	emit_water();
	progress_land();
	trace(frameNum);
}

function get_land_color(y:int, x:int):Number {
	var color:Number = (int)(landMap[0][y][0][x] * 0xFF);
	if (color &lt; 0) { color = 0 }
	if (color &gt; 255) { color = 255 }
	color = (color &lt;&lt; 16) | (color &lt;&lt; 8) | color; // maps to grey of RGB
	return(color);
}

function get_water_color(y:int, x:int):Number {
	var color:Number = 0;
	if (waterMap[0][y][0][x] &gt;0)
		color = (waterMap[0][y][0][x] + landMap[0][y][0][x]) * 0xFF;

	if (color &lt; 0) { color = 0 }
	if (color &gt; 255) { color = 255 }

	// the below line draws the water in greyscale, otherwise shades of blue
	// as in an RGB value, the blue is in the least significant digits
	//color = (color &lt;&lt; 16) | (color &lt;&lt; 8) | color; // maps to grey of RGB
	return(color);
}

/*
function save_screenshot():void {
	var jpgSource:BitmapData = new BitmapData (stage.stageWidth, stage.stageHeight);
	jpgSource.draw(stage);

	var jpgEncoder:JPGEncoder = new JPGEncoder(100);
	var jpgStream:ByteArray = jpgEncoder.encode(jpgSource);
	var file:FileReference = new FileReference();

	file.save(jpgStream, 'riseLand-'+frameNum+'.jpg');
}
*/

function emit_water():void {
	if (alreadyEmitted &lt; maxEmitted) {
		if (waterMap[0][int(resY*.30)][0][int(resX*0.95)]&lt;.3) {
			waterMap[0][int(resY*.30)][0][int(resX*0.95)] += .2;
			alreadyEmitted += .2;
		}
		if (waterMap[0][int(resY*.10)][0][int(resX*0.45)]&lt;.3) {
			waterMap[0][int(resY*.10)][0][int(resX*0.45)] += .1;
			alreadyEmitted += .1;
		}

		if (waterMap[0][int(resY*.85)][0][int(resX*0.15)]&lt;.3) {
			waterMap[0][int(resY*.85)][0][int(resX*0.15)]+= .05;
			alreadyEmitted += .05;
		}
	}
}

var landAdded:Number = 0;
var landMax:Number = 200;
var cur_landshift:Number = 0;
var max_landshift:Number = 100;

function progress_land():void {
	var proposedX:int;
	var proposedY:int;

	// these are the land emitters in the center.
	if (landAdded &lt; landMax) {
		landMap[0][int(resY*.5)][0][int(resX*0.5)]+= 2;
		landAdded += 2;
	}

	cur_landshift++;
	if (cur_landshift &gt; max_landshift) { return; }

	for (var k in landMap[0]) {
		for (var i in landMap[0][k][0]) {
			for ( var neighborX:int=-1; neighborX&lt;=1; neighborX++) {
				for ( var neighborY:int=-1; neighborY&lt;=1; neighborY++) {
					proposedX = i+neighborX;
					proposedY = k+neighborY;
					if (
						(proposedX&lt;0) || (proposedY&lt;0) ||
						(proposedX&gt;resX-1) || (proposedY&gt;resY-1)
					) {
						//trace('skipping land edge');
					}
					else {
						shift_land(i, k, proposedX, proposedY);
					}
				}
			}
		}
	}
}

function shift_land(curX:int, curY:int, checkX:int, checkY:int):void {
	var delta:Number = landMap[0][curY][0][curX] - landMap[0][checkY][0][checkX];
	delta *= .5;
	landMap[0][curY][0][curX] -= delta;
	landMap[0][checkY][0][checkX] += delta;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.MikeRandrup.com/2011/11/3d-land-water-coding-experiment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Work Stuff: Loading Animation for native iPhone App</title>
		<link>http://blog.MikeRandrup.com/2011/10/work-stuff-loading-animation-for-native-iphone-app/</link>
		<comments>http://blog.MikeRandrup.com/2011/10/work-stuff-loading-animation-for-native-iphone-app/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 16:25:04 +0000</pubDate>
		<dc:creator>mikerandrup</dc:creator>
				<category><![CDATA[projects]]></category>
		<category><![CDATA[Adobe CS5]]></category>
		<category><![CDATA[After Effects CS5]]></category>
		<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.MikeRandrup.com/?p=426</guid>
		<description><![CDATA[Earlier this year, I worked on the graphics used in a Native iPhone App (now live on the App Store) for www.SplashCoupons.com. The app lists offers for home improvement savings for people in the North Dallas, Texas area. When the App first launches, it downloads the latest set of coupons from a data server via]]></description>
			<content:encoded><![CDATA[<p><a href="http://itunes.apple.com/us/app/splashcoupons/id434254471?mt=8"><img src="http://blog.MikeRandrup.com/wp-content/uploads/2011/10/loading-anim-iphonescreenshot.jpg" alt="" title="Screenshot of loading animation" width="115" height="251" class="alignright size-full wp-image-436" /></a><br />
Earlier this year, I worked on the graphics used in a Native iPhone App (<a href="http://itunes.apple.com/us/app/splashcoupons/id434254471?mt=8">now live on the App Store</a>) for <a href="http://www.SplashCoupons.com">www.SplashCoupons.com</a>.  The app lists offers for home improvement savings for people in the North Dallas, Texas area.  When the App first launches, it downloads the latest set of coupons from a data server via XML.  During this process, which can take a couple of seconds, I wanted to display a visually interesting animation.  So out came the storyboard, and a new After Effects project was born.</p>
<p><a href="http://itunes.apple.com/us/app/splashcoupons/id434254471?mt=8"><img src="http://blog.MikeRandrup.com/wp-content/uploads/2011/10/appstore.gif" alt="" title="See the free App in action on the App Store" width="162" height="56" class="alignleft size-full wp-image-443" /></a>Conceptually, the animation was designed to show a user that &#8220;coupons&#8221; are going &#8220;into their iPhone&#8221;.  The After Effects project was relatively simple.  The coupon image assets I created were animated along paths from off screen into the pulsing iPhone in the middle.  The screen of the iPhone has an AJAX-style busy cursor superimposed on it.  Two layers of After Effects &#8220;Particle Playground&#8221; effects were blending with a glow effect.  Since the particle filter naturally emits from the center outward, I time reversed the particle composition so the particles would flow into the iPhone.  There is a colored glow in the center, and concentric circles pulsing inward.  The last element, &#8220;droplet&#8221; pieces of the Splash Coupons logo, fly outward from the phone.  The color decisions were based on the style guide for the Splash Coupons logo and brand.</p>
<p>The end deliverable for the animation was an 18 frame looping sequence.  It didn&#8217;t take up much memory or room in the IPA file, and loops to run as long as needed.  I also provided several other button graphics for the user interface.</p>
<p>Hopefully it makes for a nicer wait as the XML downloads in the background.  At any rate, it was fun to create.</p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/0OWAP2DY5PE?rel=0" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.MikeRandrup.com/2011/10/work-stuff-loading-animation-for-native-iphone-app/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Difficult Day in Non-Profit Land</title>
		<link>http://blog.MikeRandrup.com/2009/05/a-difficult-day-in-non-profit-land/</link>
		<comments>http://blog.MikeRandrup.com/2009/05/a-difficult-day-in-non-profit-land/#comments</comments>
		<pubDate>Sun, 24 May 2009 00:48:07 +0000</pubDate>
		<dc:creator>mikerandrup</dc:creator>
				<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://blog.MikeRandrup.com/?p=253</guid>
		<description><![CDATA[The local environmental non-profit group I&#8217;m involved with had a significant event happen in its history today.  Due to a variety of factors (primarily budget shortfall issues), the board today voted to become an all-volunteer organization effective at the end of June 2009.  This is a huge change: the original founder had been a full-time,]]></description>
			<content:encoded><![CDATA[<p>The local environmental non-profit group I&#8217;m involved with had a significant event happen in its history today.  Due to a variety of factors (primarily budget shortfall issues), the board today voted to become an all-volunteer organization effective at the end of June 2009.  This is a huge change: the original founder had been a full-time, paid contractor prior to this point.  No longer will this be the case, and the process of creating this change is a major one that has big consequences for the founder.  No one likes to change jobs, even if their paycheck was sporadic at best.  No one likes to release the reins of their own creation.</p>
<p>Our board has bitten off a huge responsibility to ensure that the organization continues to fulfill its mission, and to properly honor the contributions, vision, and work of our founder.</p>
<p>Let&#8217;s just say that it all made for a pretty heavy board meeting.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.MikeRandrup.com/2009/05/a-difficult-day-in-non-profit-land/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Turning Desktop Wallpaper into Real Wallpaper</title>
		<link>http://blog.MikeRandrup.com/2009/04/turning-desktop-wallpaper-into-real-wallpaper/</link>
		<comments>http://blog.MikeRandrup.com/2009/04/turning-desktop-wallpaper-into-real-wallpaper/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 19:33:49 +0000</pubDate>
		<dc:creator>mikerandrup</dc:creator>
				<category><![CDATA[homeownership]]></category>
		<category><![CDATA[ideas]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://blog.MikeRandrup.com/?p=214</guid>
		<description><![CDATA[   For this project, I picked an area up my upstairs office that was nestled between some built in shelves and cabinets on one wall.  It measured 48 inches wide by 33 inchess tall. Next I went to my favorite free high resolution desktop wallpaper sites, and looked for something that I wanted to see]]></description>
			<content:encoded><![CDATA[<p><img style="-webkit-user-select: none" src="http://blog.mikerandrup.com/wp-content/uploads/2009/04/1-full-size-wall-print-bare-wall-150x150.jpg" alt="" /> <img style="-webkit-user-select: none;" src="http://blog.mikerandrup.com/wp-content/uploads/2009/04/2-full-size-wall-print-installed-no-trim-150x150.jpg" alt="" /> <img style="-webkit-user-select: none;" src="http://blog.mikerandrup.com/wp-content/uploads/2009/04/0-full-size-wall-print-end-result-150x150.jpg" alt="" /></p>
<p>For this project, I picked an area up my upstairs office that was nestled between some built in shelves and cabinets on one wall.  It measured 48 inches wide by 33 inchess tall.</p>
<p><img style="-webkit-user-select: none;" src="http://blog.mikerandrup.com/wp-content/uploads/2009/04/1-full-size-wall-print-bare-wall-320x240.jpg" alt="" /></p>
<p>Next I went to my <a href="http://www.hdrwalls.com/categories.php?id=2">favorite free high resolution desktop</a> <a href="http://www.google.com/search?hl=en&amp;rlz=1C1GGLS_en-USUS299US303&amp;q=desktop+wallpaper+1680&amp;btnG=Search">wallpaper sites</a>, and looked for something that I wanted to see on my wall.  I wanted to find something that included obvious perspective cues to give the illusion of depth, and seemed to have a light source in the middle of the picture where my lamp was going to be shining from.  I <a href="http://www.hdrwalls.com/comments.php?id=372">picked this one </a>without over-thinking it too much for the purposes of the experiment.  Many others would have worked, and been much more interesting.  I downloaded it at the highest resolution offered (2,560 x 1,600 pixels).</p>
<p><img style="-webkit-user-select: none;" src="http://blog.mikerandrup.com/wp-content/uploads/2009/04/butler_at_library_columbia_university_800x600-320x240.jpg" alt="" /></p>
<p>In order to know how my photo would look, I divided the number of pixels I had wide by inches wide (2,560 pixels/48 inches) = 53 DPI (dots per inch).  For a section of wall that people will be at least 1-3 feet away from, 50 DPI is fine.  100 DPI is good if people will get less than a foot away at eye level to your wall.  This requires less DPI than other printing applications in order  to look good from the distance a viewer sees it.</p>
<p>Next I went to an online printing place to have it printed large.  <a href="http://www.bargainbanners.com/product_info.php?cPath=22&amp;products_id=28">I went to BargainBanners.com, (my employer), here</a>.   My wallpaper printout arrived well within a week.</p>
<p><img style="-webkit-user-select: none;" src="http://blog.mikerandrup.com/wp-content/uploads/2009/04/2-full-size-wall-print-installed-no-trim-320x240.jpg" alt="" /></p>
<p>When it arrived, I thumb-tacked it to the wall under where the trim was attached.</p>
<p><img style="-webkit-user-select: none;" src="http://blog.mikerandrup.com/wp-content/uploads/2009/04/3-full-size-wall-print-lighting-matches-photo-320x240.jpg" alt="" /></p>
<p>Since there is a lamp that goes on that part of the shelf, I set it up without its shade to preview how the room&#8217;s real lighting would work with the image.  Looks like the bulb is practically part of the sky.  Exactly the effect I was hoping for.</p>
<p><img style="-webkit-user-select: none;" src="http://blog.mikerandrup.com/wp-content/uploads/2009/04/0-full-size-wall-print-end-result-640x457.jpg" alt="" /></p>
<p>Wood trim, lampshade, and various office junk put back into place.  I&#8217;m pretty happy with how it turned out for a first try.  What does everyone else think?  I have more complicated wood paneling elsewhere in the house.  I was thinking of trying something more complex, with a more meaningful image, in the future.</p>
<p>Regarding the copyright of the image, that part is sticky.  I believe it would be a better practice to surf on over to iStockPhoto.com to buy the proper rights to an image they have for $5-$12.  Better yet, if you have a camera with a lot of megapixels, you can print directly from your photographs, which you already own.  My employer sees a lot of this for beautiful engagement photos on huge display at the wedding reception.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.MikeRandrup.com/2009/04/turning-desktop-wallpaper-into-real-wallpaper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

