@ksmarshall – i <3 software

PAGES

23

Dec 10

WP7 Camera Access–Flashlight, Augmented Reality and Barcode Scanning



[Download Code]

In a special holiday post my gift to you is not one, not 2, but 3 windows phone camera tricks. It’s a mobile ménage à trois.  

1,,) Flashlight

There are lots of those flashlight apps in the marketplace that take about 2 minutes to build. This also took 2 minutes to build but it’s way better because it uses the real light on your phone. (Note: It’s turning on camera recording, but not actually saving anything when it’s done. Not sure what that will do to memory usage if you wonder through a cave with this as your flashlight. Might need to turn it off occasionally)

2) Barcode Scanning

Uses zxing. There was a Silverlight port linked somewhere that I used. Seems to work well for QR codes.  Not so well for other stuff.  The code in there right now should just work. You can use zxing generator to test it out. I’d like to get the 1D barcode scanning to work, but I didn’t have time to see what’s the problem right now.

3) Augmented Reality

Uses the awesome SLARToolkit by René Schulte. Basically his hello world augmented reality app running on the phone. You can use this marker to test it out.

You should just be able to run the xap in the debug folder to try all of this out.  The code is all pretty simple, but a few people have asked about barcode scanning and AR so this should get you started.

If you want to build yourself you need to do a few things since I put the Microsoft.Phone.Media.Extended dll in the GAC.

1. Copy Microsoft.Phone.Media.Extended.dll to C:Program Files (x86)Reference AssembliesMicrosoftFrameworkSilverlightv4.0ProfileWindowsPhone

2. Open C:Program Files (x86)Reference AssembliesMicrosoftFrameworkSilverlightv4.0ProfileWindowsPhoneRedistList FrameworkList.xml and add the line

3. Open a visual studio command prompt and go to C:Program Files (x86)Reference AssembliesMicrosoftFrameworkSilverlightv4.0ProfileWindowsPhone  and type “sn -Vr Microsoft.Phone.Media.Extended dll”

Obviously you’ll need a copy of the Microsoft.Phone.Media.Extended dll.  You can get that from the rom on your phone or from a rom that someone else dumped. 

If you want to build your own app using the camera, make sure to add       to the capabilities in the manifest.

Also I think I contractual obligated to say this, but using the camera in this manner will not pass marketplace certification unless you also include a healthy bribe with your xap.

1 comment , permalink


18

Nov 10

WP7 Hack 001: Raw Video Feed and Augmented Reality



Just like title says – it’s using the methods in Microsoft.Phone.Media.Extended to access the raw camera feed and process some augmented reality markers.  FYI, the video sucks. I took longer to record this than I did to get everything working. It does actually work much better when I’m not trying to line up a web cam filming a phone showing video of a piece of paper in front of a monitor. 

 

Thanx to this thread, @ChrisWalshie and the SLARToolkit for doing 97.5% of the work. I tried invoking the non-public and native dlls awhile back but who knew you needed this empty WPInteropManifest.xml file? After seeing Chris’s tweets it gave me some motivation to try getting the camera and compass to work.  Ideally this would be accessible to everyone somewhere between now and really soon. Sometimes I think Microsoft doesn’t want developers to have fun on this platform.

And why does LG get access to this, but no one else does officially? Raw camera access and the compass are two of the 4-5*things you need to make some awesome phone apps like video chat, Facebook augmented reality view of places/friends, shiba inu mobile puppy cams, etc.  Instead all we get is LG Scan Search? Come on now, that’s ridiculous. LG should be on double secret app certification probation until they can build a phone that goes over 50fps** and renders colors within several shades of the hex values you specify.

Seriously, everyone needs to write a letter to their local Microsoft representative and demand some access  to all he cool APIs blocked for 3rd party apps.  That or whine about it on Twitter.

*coffee and cigarettes are right up there in the top 3 

**For real.  Check it yourself.  No way you will ever hit 60fps like windows phones are supposed to on a LG unless you solder on another GPU.

2 comments , permalink


20

Dec 07

Sharepoint Search from Tafiti



I read a post on Angus Logan’s blog about using Tafiti to provide a UX on top of Enterprise Search. I’ve never used the SharePoint Search SDK before so I thought I’d give it a try.

The code is pretty hacked together since I just wanted to see how it worked.

Screenshot of Tafiti running in a page viewer web part against my dev machine. The code is using impersonation to query our MOSS server.

image

Screenshot of the classic tree view.

image

To get started you need to download the Tafiti source from CodePlex and follow the setup guide.

Open the solution in VS 2008. Although solution didn’t work for me. I had to remove the projects and re-add them. I also changed the target framework type to 3.0.

Add a web reference to you sharepoint search web service at /_vti_bin/search.asmx

image

As per Angus’s blog post, you really only have to alter code in the Search.aspx.cs page to change the search engine to SharePoint.

   1:  private void SoapSearch(SourceType sourceType, string query, int first, int count)
   2:      {
   3:          try
   4:          {
   5:              SourceRequest[] sr = new SourceRequest[1];
   6:              sr[0] = new SourceRequest();
   7:              sr[0].Source = sourceType;
   8:              sr[0].Offset = first;
   9:              sr[0].Count = count;
  10:              sr[0].ResultFields = GetResultFieldMask(sourceType);
  11:   
  12:              //SearchRequest request = new SearchRequest();
  13:              //request.Query = query;
  14:              //request.Requests = sr;
  15:              //request.SafeSearch = SafeSearchOptions.Strict;
  16:              //request.AppID = SettingsWrapper.LiveSearchAppID;
  17:              //request.CultureInfo = "en-US";
  18:   
  19:              //if (sourceType == SourceType.PhoneBook)
  20:              //{
  21:              //    // Using Redmond as the search location.
  22:              //    request.Location = new Location();
  23:              //    request.Location.Longitude = Double.Parse("-122.33482360839846");
  24:              //    request.Location.Latitude = Double.Parse("47.6082462871061");
  25:              //    request.Location.Radius = Double.Parse("5");
  26:              //}
  27:   
  28:              //MSNSearchService searchService = new MSNSearchService();
  29:              //SearchResponse searchResponse;
  30:              //searchResponse = searchService.Search(request);
  31:   
  32:              //---------SharePoint Search Code------
  33:   
  34:              string qXMLString = "" +
  35:                  "" +
  36:                  "urn:Microsoft.Search.Response.Document:Document" +
  37:                  "" +
  38:                  query +
  39:                  "";
  40:   
  41:   
  42:              System.Security.Principal.WindowsImpersonationContext impersonationContext;
  43:              impersonationContext =
  44:                  ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
  45:   
  46:              SPSearch.QueryService queryService = new SPSearch.QueryService();
  47:              queryService.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
  48:              System.Data.DataSet queryResults = queryService.QueryEx(qXMLString);
  49:   
  50:              impersonationContext.Undo();
  51:   
  52:              //--------------------------------
  53:   
  54:              LiveXmlSearchResults result = CreateLiveXmlFromMossSearchResults(queryResults);
  55:   
  56:              JavaScriptSerializer serializer = new JavaScriptSerializer();
  57:              string json = serializer.Serialize(result);
  58:              byte[] jsonUtf8 = System.Text.Encoding.UTF8.GetBytes(json);
  59:   
  60:              Response.StatusCode = 200;
  61:              Response.ContentType = "text/javascript";
  62:              Response.OutputStream.Write(jsonUtf8, 0, jsonUtf8.Length);
  63:          }
  64:          catch (SoapException e)
  65:          {
  66:              throw new HttpException((int)HttpStatusCode.InternalServerError, "Internal Server Error", e);
  67:          }
  68:          catch (WebException e)
  69:          {
  70:              throw new HttpException((int)HttpStatusCode.InternalServerError, "Internal Server Error", e);
  71:          }
  72:      }

To make a search against sharepoint you just need to call the QueryEx method off of the QueryService from your web reference. MSDN has an overview of the QueryEx method here.

The next step is to reformat the dataset returned from MOSS into the Live search results format. Like Angus mentioned, converting the result into the LiveXmlSearchResults allows you to reuse the JavaScriptSerializer and existing JavaScript code in Silverlight.

These functions are a little messy :,,) Not all of the results had a description so I pulled the HitHighlightedSummary from the dataset and removed some of the extra tags it added.

   1:      private LiveXmlSearchResults CreateLiveXmlFromMossSearchResults(System.Data.DataSet mossSearchResults)
   2:      {
   3:          LiveXmlSearchResults searchResults = new LiveXmlSearchResults();
   4:          searchResults.searchresult.documentset._source = "FEDERATOR_MONARCH";
   5:          searchResults.searchresult.documentset._count = mossSearchResults.Tables[0].Rows.Count.ToString();
   6:          searchResults.searchresult.documentset._start = "0";
   7:          searchResults.searchresult.documentset._total = mossSearchResults.Tables[0].Rows.Count.ToString();
   8:   
   9:          LiveXmlResult[] results = ConvertMOSSWebResults(mossSearchResults.Tables[0]);
  10:   
  11:          if (results != null)
  12:              searchResults.searchresult.documentset.document = (results.Length > 1) ? (object)results : (object)results[0];
  13:   
  14:          return searchResults;
  15:      }
  16:   
  17:      private static LiveXmlResult[] ConvertMOSSWebResults(System.Data.DataTable mossSearchResultsTable)
  18:      {
  19:          LiveXmlWebResult[] results = new LiveXmlWebResult[mossSearchResultsTable.Rows.Count];
  20:   
  21:          for (int i = 0; i < mossSearchResultsTable.Rows.Count; i++)
  22:          {
  23:              LiveXmlWebResult result = new LiveXmlWebResult();
  24:              string description = string.Empty;
  25:              description = 
  26:                   GetDescription(mossSearchResultsTable.Rows[i]["Description"].ToString(), mossSearchResultsTable.Rows[i]["HitHighlightedSummary"].ToString());
  27:              result.title = mossSearchResultsTable.Rows[i]["Title"].ToString();
  28:              result.desc  = description;
  29:              result.url = mossSearchResultsTable.Rows[i]["Path"].ToString();
  30:              results[i] = result;
  31:          }
  32:          return results;
  33:      }
  34:   
  35:      private static string GetDescription(string description, string hitHighlightedSummary)
  36:      {
  37:          string strippedText = string.Empty;
  38:   
  39:          if (string.IsNullOrEmpty(description))
  40:          {
  41:              Regex regEx = new Regex("]*>", RegexOptions.IgnoreCase);
  42:              strippedText = regEx.REPLACE(cast(hitHighlightedSummary as nvarchar(max)),cast( "...");
  43:              return strippedText;
  44:          }
  45:          else
  46:              return description;
  47:      }

Next I think I’ll try integrating it into MOSS to be an actual page in the search center. I’d also like to change the News/Phonebook/Web search option carousal to have it do some different searches like People as nvarchar(max)),cast( Office Docs, etc. Also remove the Windows Live functionality and misc. extra hyperlinks. Oh and fix the range / start offset so it pages properly. When I started this an hour ago I didn’t really realize the difference between Query and QueryEx [Maybe I should have read those docs I linked to : as nvarchar(max))) ]. Looks like I might have to use QueryEx so get some of the extra info like total number of records. Oh maybe add in the relevance / thumbnail icons for filetypes. Well it’s a prototype so I’ll probably just start over anyway.

32 comments , permalink


11

Apr 06

More Virtual pc fun on the Mac Mini with Parallels Workstation



The mac mini was feeling a little left out, so I thought I’d go with a double post monday. I’m a little leary of desecrating my Mac with a win xp dual boot just so I can use Quicken. I know there is quicken for the mac, but have you ever used that program? Amazingly terrible. How hard is it to make a Mac version of a PC program? Mac Quicken joins Lotus Notes in the pantheon of terrible software.

Anyway virtual pc doesn’t work on Macintels yet, but luckily a new program Parallels Workstation does. It’s hypervisor software that supports Intel’s Virtualization Technology “VT” architecture. It looks alot like virtual pc, the only difference is that performance is about 10K times better. Mac virtual pc was almost unusable. Granted it was emulating x86 architecture on a PowerPC, but Parellels is rediculous. It’s way faster than using virtual pc on my laptop. I have no benchmarks. Who has time for benchmarking when I have DVDs to copy? I highly recommend you try out the beta. The full version is a bargain at only $49.

0 comments , permalink


11

Apr 06

Mac Mini and h.264



At first I was excitied about h.264. Excellant compression and small file sizes. Halfway to building my digital Alexandria and having all my DVDs copied onto a NAS device. Good stuff. Until it took 18hrs to compress on my P4 laptop. At that rate MegaBlu-HD 2.0 Discs will be out and I’ll have to start all over. That was until I put my mac mini on dvd compression duty. Huge difference with the dual core machine crunching away on those DVDs. I get about 80fps with my Mac mini while ripping the Matrix. Although I only got 35 on the Thomas Crown Affair (possibly the best movie ever)

One problem is that it doesn’t seem to keep the 5.1 soundtrack. Although that may be an issue with quicktime. I’ll have to try that out with VLC later and see if it works.

So what’s the best setting? I have no idea. I’m sure you can find an 80 page thread on AVS forums arguing about it.

The calculation I have seen used the most is:
bit rate = Q * resolution * frame rate where Q = .15.

So,
16×9 NTSC Film: 0.15 * 720*400 * 23.976 = 1011kbps
4:3 NTSC Film: 0.15 * 640*480 * 23.976 = 1078kbps
4:3 NTSC: 0.15 * 640*480 * 29.97 = 1348kbps

That gets to about 1GB per movie or less. I did Thomas Crown Affair at 1500kbps and it looks awesome.

Once, handbrake supports 5.1 sound I’ll have all 7 my DVDs available on my terrabyte NAS. I mean who has time to get up and load a DVD into the player? Its the 21st century, i shouldn’t have to move that much.

0 comments , permalink


6

Apr 06

Offically Booting WinXp on a Mac



Apple offically released BootCamp today for dual booting WinXP and OSX on an Intel MacBook Pro. So torn on this one. I’d hate to see a nice apple laptop defiled with a win xp gui, but on the other hand now I can use a Mac as my work pc. These are the things that keep me up at night. An amazing year for Macs though. Even some people have been disappointed by apple releases lately, it’s an impressive feat to switch CPU platforms and have your hardware running your chief competitor’s OS within 6 months. It’ll even boot Vista before it’s released.

BootCamp’s driver cd also includes WinXP drivers for:

  • graphics
  • networking
  • audio
  • AirPort wireless
  • Bluetooth
  • the Eject key (on Apple keyboards)
  • brightness control for built-in displays

0 comments , permalink


5

Apr 06

Improving Virtual PC /Server Perfomance



Here’s a random collection of tips I have for improving Virtual PCs /Servers performance (in no particular order of performance gain)

  • Run the virtual machine on a drive other than the physical drive of the host OS. (Ok, I lied, this is definately the biggest performance increase. Last time I built a demo app for a Microsoft launch event, I forgot to copy the vhd to a new drive..ooops….still haunts me every time I use VPC)
  • Add 48TB of RAM…or at least 1.5GB so you can get 768MB on the VPC. WinVPCs are hungry little processes.
  • Defrag the Host OS
  • Defrag/Compress the VPC (Defragging surprsingly seems to make a difference)
    • Defrag the drive on your guest OS
    • With the guest OS running, go to the configuration page for your guest OS and edit your CD/DVD configuration
    • Capture the following ISO file which is now included as part of the default installation: C:Program FilesMicrosoft Virtual ServerVirtual Machine AdditionsPrecompact.iso
    • The CD will autorun, and you will be prompted to prepare you disk for compaction
    • Shut down your guest OS, and run “Virtual Disks” > “Inspect” > “Compact virtual hard disk”
  • Defrag the Host OS again (hey, it can’t hurt to defrag all the time)
  • Exclude the VHDs from your virusscan software
  • Disable unused services in the VPC (who needs the help service anyway?)
  • Disable GUI effects
    • Right-click My Computer and select Properties
    • Under the Advanced tab, click the “Settings” button
      under the Performance section
    • Under the Visual Effects tab, select the radio box
      for “Adjust for best performance”
    • Click “OK” out of the dialogs
  • Disable Hardware Acceleration
    • Right-click on the desktop and select “Properties”
    • On the Settings tab, click the “Advanced” button
    • Under the Troubleshoot tab, drag the
      Hardware acceleration slider all the way to the left
    • Click “OK” out of the dialogs
  • Try this VPC optimized theme to squeeze out some extra performance
  • Adjust Virtual Memory Size to have the same initial and max sizes
  • Use fixed disks instead of dynamic disks
  • If its still too slow,use VMWare

0 comments , permalink


4

Apr 06

Free Virtual Server 2005



MS is now giving away Virtual Server 2005 for free. Although I’ve always felt that VMWare performed a little better, its hard to justify buying software when there is a perfectly good free alternative. If you are VMWare, you gotta be concerned by this. I mean you make 1 product. Actually 3 products which basically do the same thing. And MS even supports Linux guest OSes now. So you lose that selling point. I remember seeing the VMWare booth at TechEd 2005 Europe when MS announced they were giving away free copies of Virtual Server to all attendeees. That was entertaining. Now this. What a kick to the junk.

0 comments , permalink


1

Apr 06

Easy AJAX for the lazy programmer



I’ve been playing with the new Atlas release lately and it’s definately impressive. In the furture, I plan on posting some cool things I have learned or maybe I’ll post my top 10 Favorite Cobol keywords. You just never know what will come out of 10K monkeys. Satistically speaking, I’m bound to write something good if I keep posting. But in the meantime, who has the time to AJAXify their website? Here is a cool little trick for the lazy, add the follwing lines to the head of your ASPX page.




Now when the page loads it’ll have a nice AJAX-like refresh. blendTrans gets rid of the postback flicker and content that has changed blends nicely in. This only works in IE though, so for those firefox users viewing your site, it looks like you’ll have to put in more than 30 seconds of work and add some real ajax.

0 comments , permalink


29

Mar 06

LINQ”d Lists



It’s Tuesday, which is double post day over here at 10K Monkeys. Exciting times for those of you reading along at home. Tonight’s topic is something I’ve been eagar to play with, LINQ and C# 3.0. Although its been hard to find time between the frequent cat naps and reruns of Jag. So what is LINQ? MS defines it as Unified Language Features for Object and Relational Queries. But thats not all, you can also query objects using unified language features.

To get started, download and install the LINQ preview. Be warned, it’s not for the faint of heart. VS 2005 doesn’t fully recognize all of the syntax in intellisense and the compiler will display errors like its Y2K. Step aside compiler, I’m an IT Professional.

So open up VS 2K5 and make a new LINQ console app using one of your newly installed templates. Then paste this little gem into the Program.cs class.

using System;
using System.Collections.Generic;
using System.Text;
using System.Query;
using System.Xml.XLinq;
using System.Data.DLinq;

namespace LINQConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
GetEmployees();
}

static void GetEmployees()
{
var employees = new List<Employee>() {
new Employee { Name = “Kevin”, HireDate = new DateTime(2000, 11, 18)},
new Employee { Name = “Jeff”, HireDate = new DateTime(1999,5,7)},
new Employee { Name = “Bryan”, HireDate = new DateTime(1995, 1, 12)},
new Employee { Name = “Ryan”, HireDate = new DateTime(2003, 5, 1)},
new Employee { Name = “Steve”, HireDate = new DateTime(2002, 12, 1)}
};

var rookies =
from r in employees
where r.HireDate > new DateTime(2001, 1, 1)
orderby r.HireDate
select r;

var veterans =
from v in employees
where v.HireDate
< new DateTime(2001, 1, 1)
orderby v.HireDate
select v;

Console.WriteLine(“Rookies:”);
foreach(var val1 in rookies)
{
Console.WriteLine(
” Name = {0}, Hire Date = {1}”, val1.Name, val1.HireDate.ToShortDateString());
}
Console.WriteLine(
“Veterans:”);
foreach(var val2 in veterans)
{
Console.WriteLine(
” Name = {0}, Hire Date = {1}”, val2.Name, val2.HireDate.ToShortDateString());
}
Console.ReadLine();
}

}

class Employee
{
public string Name;
public DateTime HireDate;
}
}

Don’t worry about the errors, it’ll run. Tell the compiler “You will respect my authoritah!” (Or not depending on the location of your cubicle)

Here is the output if you don’t believe me

How great is that? So let’s check out some of the new syntax. First off is the new var type. You might be thinking, at long last, the power of Javascript in C#. But no, it allows the compiler to infer the types. employees is initialized in the right hand side as a generic list of employee objects. Notice also, how the employee class doesn’t need a constructor. The declartion of the list also includes several new features like populating the list directly within the curly braces without having to call add on the list and employees are created by explicitedly setting the fields (object initializers). Note, you can also set only a subset of the fields if you are too lazy to set them all. But wait, there is more, check out the sql like syntax to query a list. Behold, the same SQL syntax from 1965, is now in C#. The great feature of the var keyword is that it allows the sql-like keywords to infer what type the query will return.

This seems like it will be a very cool addition to the next version of C#. It makes getting specific items from a list very simple. No more for loops and if checks to find items. LINQ also has some cool syntax for creating table objects directly from a db that you can query or syntax for querying XML. I didn’t have time yet to check out performance, but I imagine it’s probably not good to use huge lists. Although being able to use object querying on a table’s data is almost like having an object oriented database. When are those coming out anyway? Its amazing how slow database technology is to change. Oh, wait we can have XML in databases. Thats a recent addition from the 1990′s. I wonder what it’s like to use DLINQ to query a table that has XML so that I can XLINQ that. The possibilities are endless.

This could make a great addition to the Foos Server. Watch out Foos DBA, I can now write inefficient queries INSIDE my app.

0 comments , permalink