Thursday, April 19, 2007

I took my sample and did it with a much cooler source image, namely the Tesla Roadster, which is absolutely the coolest car I can think of.

 

Thursday, April 19, 2007 12:11:50 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback

We have a cool feature in our backend data hub we call Image Overlay.  Basically given images of a vehicle we can do all sorts of transformations including overlaying text ("Buy this car!"), overlaying images ("GM Certified logo") scaling and matte-ing (shrinking the input image down to have a single color margin to draw text in) and support for various geometric primitives.  Our implementation is one of the few in our industry and is probably far more complete, flexible, and better-er than the few competing implementations.  Our backend uses some PERL stuff for this and I wondered if a .NET engine would be as fast or faster and how it would scale, given that the claim has been made that C# is 1:1 performance with C++ and despite my love of C# I found this claim questionable.  So, supposing I have an input image which is assuredly not a car:

And a tiny screenshot of my most anticipated upcoming PS3 game, LAIR:

And I want to do a few operations in realtime in .NET:

  • create a Matte
  • scale the source image
  • Add some text
  • import the Dragon screenshot from LAIR
  • Time the operation

Here is the source code for entering some parameters, which could obviously come from some other source:

<div>

<h3>Source Image:</h3>

<asp:HyperLink ID="_exampleLnk" runat="server" Target="_blank" NavigateUrl="~/sample.jpg">

View source image

</asp:HyperLink>

<br />

Matte and overlay some text:

<asp:TextBox ID="_overlayTxt" runat="server" Text="go MSFT!"></asp:TextBox>

<br />

Import Img X <asp:TextBox runat="server" ID="_xTxt" Width="2em" Text="100"></asp:TextBox>

Import Img Y <asp:TextBox runat="server" ID="_yTxt" Width="2em" Text="100"></asp:TextBox>

<asp:Button ID="_submitBtn" runat="server" Text="Lay it over" OnClick="_submitBtn_Click" />

<br />

<asp:Label ID="_resultTimeLbl" runat="server"></asp:Label>

<br />

<asp:Image ID="_resultImg" runat="server" />

</div>

... and the code behind....

protected void _submitBtn_Click(object sender, EventArgs e)
{
string getQuery = "Image.aspx?overlay={0}&x={1}&y={2}";
int x;
int y;
int.TryParse(_xTxt.Text, out x);
int.TryParse(_yTxt.Text, out y);
_resultImg.ImageUrl = string.Format(getQuery, _overlayTxt.Text, x, y);
}

... and the result...

So, on a Windows Server 2003 running ASP.Net 2.0, how much code does it take to generate this?  Surprisingly little:

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);

bool high = true;

HighResTimer hpt = new HighResTimer();
hpt.Start();
System.Drawing.Imaging.ImageCodecInfo codecInfo;
System.Drawing.Imaging.EncoderParameters parms;

System.Drawing.Imaging.ImageCodecInfo[] infoz = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
codecInfo = infoz[1];
parms = new System.Drawing.Imaging.EncoderParameters(1);
parms.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);

string txt = Request["overlay"];
int x = int.Parse(Request["x"]);
int y = int.Parse(Request["y"]);
Response.ContentType = codecInfo.MimeType;
System.Drawing.Image newImage = new Bitmap(640, 480);
System.Drawing.Image srcImage = System.Drawing.Image.FromFile(Server.MapPath("~/sample.jpg"));
System.Drawing.Image lairImage = System.Drawing.Image.FromFile(Server.MapPath("~/lair.jpg"));
Graphics g = Graphics.FromImage(newImage);

//Interpolation mode, smoothing mode, CompositingQuality,PixellOffsetMode,etc.
if (high)
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
}

try
{
//Matte color
g.Clear(Color.LightGray);

//Overlay font
Font textFont = new Font("Verdana", 9.0f, FontStyle.Bold | FontStyle.Underline);
Brush fontBrush = Brushes.Black;
//Scales the image down to matte it
g.DrawImage(srcImage, new RectangleF(0, 0, 600, 440));
g.DrawImage(lairImage, new RectangleF(x, y, 150, 84));
g.DrawString(txt, textFont, fontBrush, new PointF(10, 441));
g.DrawString("Damon Certified used o-scope", textFont, Brushes.Red, new PointF(430, 370));
hpt.Stop();
g.DrawString("RenderTime=" + hpt.Duration.ToString("n4") + "seconds", textFont, fontBrush, new PointF(10, 455));

//Stream
newImage.Save(Response.OutputStream, codecInfo, parms);
}
finally
{
if (null != srcImage)
{
srcImage.Dispose();
}

if (null != lairImage)
{
lairImage.Dispose();
}

if (null != g)
{
g.Dispose();
}

if (null != parms) // Seems to want to save in BMP anyway with this code in
{
parms.Dispose();
}
}
}

And I'd say 6/100th of a second on my very slow server (its an Emachine's POS we confiscated from someone after a pr0n escapade) is pretty good performance.  I have one bug in that it does not always save as a JPEG like I told it to but I'm sure a little research would clear that up.  So there you have it, a simple bit of image watermarking code in C#.

 

 

Thursday, April 19, 2007 11:35:38 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, April 16, 2007

http://feeds.treehugger.com/~r/treehuggersite/~3/109498577/wave_energy_gets_smarter.php

From the article:

"...Computer scientists at the University of Edinburgh are using clever software to improve the efficiency of a wave-powered generator. The machine consists of four tubes connected by hydraulic rams, which generate up to 750 kilowatts when extended and compressed by the movement of the water. When the speed and frequency of the waves changes, the machine doesn't adapt particularly well, and this is what the researchers are focusing on. By using genetic algorithms which model evolution and natural selection..."

I've done some reading about GA but have trouble thinking of problems to apply the science to, no doubt due to my incredibly shallow understanding of GA.  This is for sure an area of future research.

AI
Monday, April 16, 2007 10:46:41 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, April 12, 2007

I am hiring into my department @ CarSpot.com in downtown Milwaukee. 

Right now I am hoping for one Summer intern and one full time person based on the work that is going on.  We are doing cool stuff and growing.  As we staff up we are hoping to have some Google-eque policies such as spending part of your time on fun research projects.  I'm setting up a Quake server tomorrow as well.  We are not a .com company, however.

Do you...

  • Have .NET skills in C#
  • Understand design patterns
  • Understand UML
  • Enjoy drinking beer (we are upstairs from the Milwaukee Ale House)
  • Like an ultra-flexible work schedule
  • Like a small company environment
  • Multi-task well (we all wear many hats in a small company)
  • Like working with NUnit, CruiseControl, NCover
  • Have interest in developing cutting edge stuff that is far ahead of its time?

Ok, I had to throw the last one in.  There is room for help in Windows Forms, Compact Framework, ASP.net web services, ASP.net web forms, some win32/C++  dev, and probably some things I'm forgetting.  Forward your interest to damon.payne@carspot.com

 

Thursday, April 12, 2007 3:53:10 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, April 11, 2007

I got a new laptop yesterday: Dell inspiron, 17" screen, core 2 duo 2.13ghz, 2gb ram@667mhz, 7200rpm serial ata drive, more 3d card than one needs unless one is playing Quake4.  Hmm, sounds like we need to install Quake4 at work for Team Building.  My previous laptop was on its 4th year of service, its 2nd round of ram and 2nd hard drive, with the 2nd one looking like it was on its way out due to more and more bad sectors being found by chkdsk.

Its amazing how fast Outlook 2007, Visual Studio 2005, etc. run with the fastest hardware Dell would currently sell me. 

 

.NET | Rant
Wednesday, April 11, 2007 12:26:41 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, April 08, 2007

I thoroughly enjoyed GrindHouse this weekend.  Surprisingly it was Jen's idea to go see it as she is also a fan of Sin City and the various Tarantino films.  While a bit long at 190 minutes I haven't enjoyed a film this much in a long time.  Not everyone will appreciate the gore filled double feature; they are chocked full of Hollywood insider nonsense.  Rose McGowan is dating Robert Rodriguez, nearly the entire cast of both films have previously appeared in Tarantino or Rodriguez films, "Zoe Bell as herself" did Uma Thurman's stunts in Kill Bill 1 & 2. Eli Roth, director of Hostel (presented by Tarantino), plays a small roll in Death Proof.  And so on, and so forth, I'd have to watch it a few more times to catch probably even half the Hollywood insider crap.

Two big successful directors with a large studio backing them and an-all star cast spoofing/praising low-budget camp horror films works despite the irony.  The fake movie trailers before and in-between the features are hilarious and may be the best part of Grindhouse. 

Sunday, April 08, 2007 10:08:24 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Wednesday, April 04, 2007

Got a PS3?  Join the Blu-Ray.com folding team, # 56895.  I'm going to let mine fold for a while to see if the team moves up the ranks at all.

http://folding.stanford.edu/

http://folding.stanford.edu/FAQ-PS3.html

http://fah-web.stanford.edu/cgi-bin/main.py?qtype=teampage&teamnum=56895

My name is "drpayne", which is also my playstation network id in case anyone is interested in beating me at MotorStorm. 

As soon as the SplitFish comes out for the PS3 I think I'll start playing FPSs competetively again, I absolutely cannot play these games (like Resistance) with a console controller.  It ain't natural.

Wednesday, April 04, 2007 2:00:24 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, April 03, 2007

Why would you want to take something very technical, such as the Visual Studio designer environment, and put it into the hands of end users?  I suppose it depends on who your end users are.  In my case, I had a controlled group of people who needed a WYSIWYG way to design window stickers for cars, a tool with deep integration into our backend and handheld systems.  When I was given the first example background PDF I realized this was doable.  I can create an image that is exactly %print resolution% x 8.5" x 11", and my handheld ONLY supports printing at 72dpi.  Easy enough: make a background image that's 612x792 pixels.  1 pixel on screen=1 point on my printed document, and I'm on my way to creating a window sticker designer.  Here's a simple example of the beta of my new designer using the VS2005 surface:

While the Visual Studio designer surface is not Visio, it does work well for things that need to be shown in spatial relations to other things, and in some cases allows user interface design elements to be chosen after deployment, and by someone besides me.  You can see here I have the basic elements you see in VS2005: a toolbox, a property grid, and a surface I am dragging and editing controls on.  An XML file format describes the locations of various things on the form.  So, how did I build this?  Its about 6000 lines of not very straightforward code before you get into anything specific to your problem domain.  Speaking of problem domains, could you use DSL tools for this type of thing?  Maybe, but I have quite a bit of control by hosting this myself and of course I'm not distributing Visual Studio to non-programmers.  In a future project, I may look into what it would take to host the DSL tools outside of visual studio, but I expect its fairly similar to what I'm doing here.  Anyway, as far as building this, I thought I'd see if the VS Class Diagram tool could reverse engineer some relationships for me before I get into code.  No such luck:

 

 

I gave up after this point, although these are some of the most important classes,  so I'll need to invest some time into StarUML or just jump into code.  Its a long road to getting a Form to show up in designable fashion, stay tuned.

Tuesday, April 03, 2007 2:15:00 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback

I'm getting ready to bust out a series of articles on Hosting the Visual Studio Designer Surface.  Controls, Designers for Controls, drag 'n drop life, ISite, and the myriad jungle of nonsense needed to make the Property Grid do just what you want it to.

One complaint you'll hear over and over again is this: surely there must be a better way to create my controls' contract with their designer than Class and Property level attributes?

/// <summary>
/// Show a dotted line warning the sticker margin vs. the page margin
/// </summary>
[Browsable(true)]
[Description("Vertical margin size in fractions of an inch")]
[EditorBrowsable(EditorBrowsableState.Always)]
[DefaultValue(.25f)]
[DisplayName("V. Margin")]
public float VerticalStickerMargin
{
   get { return _verticalMargin; }
set
{
_verticalMargin = value;
Invalidate();
}
}

Next up, some designer classes.

 

Tuesday, April 03, 2007 1:43:26 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback

I looked into getting a new laptop for work, and I'd really like to run Vista on it since VS2005 seems to be working fine now, however, one of the applications I have to support is my good old friend the Windows CE 4.2/Compact Framework application.  Mobile Device Center only works for Windows Mobile 2003 and later systems.  Active Sync does not install or work on Vista.  Just like when CF2 came out without CE4.2 support (thankfully patched later) I'm left in the lurch.  Curse you, Microsoft, for leaving a large number of people high and dry once again.

Luckily it seems Dell can offer Windows XP if you order from the business division, which I've never thought they were able to do before.  I could always get it w/Vista and wipe it right away but what fun is that?  Maybe w/Virtualizaiton I could create an XP install for working on this one product, but  I'm not sure how much hardware Virtual PC gives you access to though.  I guess I'll be trying it on my vista desktop.

{edit: USB is explicitly not supported for performance reasons.  Guess I'm running XP until my products sunset 5 years from now?  Give me a break, Microsoft}

Tuesday, April 03, 2007 11:55:39 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback

My Monday was interesting.  The high point arrived at 9:30am when my accountants called with the lowdown on 2006 taxes, seems I saved too much $$ aside for my business taxes so Damon is getting a new laptop.  Its never good when the high point arrives so early...

I was to meet some business associates at the Brewer's Opening Day around 10:30.  I've been to games in the new ballpark before so I thought I knew how much traffic to expect.  I was to show up to cook veggie kabobs (I have a mixture and method I think is pretty good though I'm not a vegetabletarian) for the vegetarians and people who think Brats are unhealthy.  Once I got close to the stadium, it took me from 10:20 until 12:30 to go the last 4 miles.  Already super late because of this, I then follow the parking herd only to realize that all forms of parking are sold out and I have to park on National Avenue; let's just say its as far as I could be from where I needed to get to.  (For Milwaukeans: 41st and National to the East end of the North Lot, Giants 2)  So I got my out of shape self to run the 3 miles and stayed at the game for a while.

I picked my daughter up from daycare to learn she's finally done running a 105deg fever.  I got around to beating God of War 2 last night as well, they are obviously getting ready to start God of War 3 on the PS3.  I'm not sure if the ending was as satisfying as God of War but the game overall was better.

Tuesday, April 03, 2007 9:43:20 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Friday, March 30, 2007

For me, it comes down to a question of innovation and real-world improvement.  Is find . -name *cpp -exec ls {} (or similar) still the best way to find files on a computer?  If I want to know rougly how large a project is, is find . -name *java |xargs wc -l the best way to see how many lines of code the team has produced?  Is make the best way to group many files into a single logical output?  Are ex macros the best way to refactor your code?

Is James Gosling's statement that most real development is still done in emacs (Java developer's journal, July 2000)the most bullshit words to be spoken since "No one will ever need more than 640k..." ?

.NET | Rant
Friday, March 30, 2007 11:25:46 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  |  Trackback