Fluxify gets smarter

Posted by jeff on Oct 3rd, 2007

Have you ever opened a huge JPEG in your browser, only to watch it slowly download, filling up line-by-line? More than likely, this means the file is a so-called "baseline" mode JPEG. It's great for digital cameras, because it is relatively simple to encode a baseline JPEG, which means you can take pictures faster, but it's somewhat non-ideal for web display because of the sequential loading behavior.

Different JPEG encodings of a sea turtle

There's a different JPEG mode called "progressive" which improves the situation a bit. Conceptually, it is useful (and quite accurate) to think of progressive JPEGs as first containing a "blurry" version of the image, followed by a series of refinements which sharpen the image, until you arrive at the final, crisp, version. There's a lot of added flexibility in the progressive mode. For example, you could first sharpen an important part of the image (say, the sea turtle's face) and get around to the rest of the image later. In some cases, it is also possible to maintain the same level of quality while shrinking file size, but doing so requires a sophisticated JPEG encoder. Progressive JPEGs are also more difficult to decode, because the information in each pixel is scattered across the file.

I have been spending most of my spare time (and some of my non-spare time) adding progressive JPEG support to Fluxify. I just applied the update to our server, and while there is nothing visibly noticeable, Fluxify should "just work" with progressive mode JPEGs. It also turns out that there was a bug that prevented us from sending grayscale JPEGs, which is fixed now, too.

So, now you can go learn all about JPEG on Wikipedia. The Progressive JPEG article isn't written yet. Any takers?

Fluxify: A simpler way to resize and email your photos

Posted by adamjh on Sep 21st, 2007

We've been incognito for awhile, but that doesn't mean we've been lazy. We spent the last seven days or so building a free service, to which the rest of this post is dedicated.

If you have a digital camera and have ever tried to email photos to friends or family, you've probably been faced with an inconvenient set of tasks that goes something like this:

  1. Make a copy somewhere on your computer of all the large photos you want to send so that you can resize them first in order to keep the size of the email down.
  2. Use a graphic design or imaging program to resize the newly created photo copies (insert many extra steps here if your program cannot do batch resizes or if you end up surfing the web to find and install shareware that can).
  3. If you use a web-based email service such as Gmail, compose a new message, then individually browse to and attach each resized photo to your message. Send.
  4. Switch contexts again out of your email and clean up those photo copies you made in step one.

If you're like me, you just find this cumbersome and annoying. If you're like my Mom and Dad (who do own a digital camera that produces 12 megapixel photos), the barrier is so high that you simply don't bother to try.

To make this easier and more accessible to everyone, we've published a web-based tool we're calling Fluxify that lets you automatically resize, upload, and email photos... without the effort.

Fluxify ScreenshotIt's free, and it doesn't require you to create an account. It should work in at least Firefox and IE, and on both a Mac and a PC. We built fluxify in Silverlight, and so you'll be prompted to install the Silverlight browser plugin if you've never visited a Silverlight-enabled site before (just like the first time you run Flash).

Fluxify is interesting in that it resizes your photos before it uploads them, saving you time and bandwidth. For web developers, we think this is a pretty revolutionary cross-platform capability: You can drop the "Max file size: 500KB" fine print (just resize it on the client-side), and avoid using cumbersome ActiveX/Java alternatives to achieve the same result.

We'll be posting another entry with more technical details on how we built Fluxify, what's going on behind the scenes, and how developers can incorporate similar client-resize features into their own services on the web. For now, we've assembled some details on the about page.

Check it out and let us know what you think!

Twiistup 2: Three unanswered questions

Posted by jeff on Aug 9th, 2007

Tonight we headed to the Twiistup 2 event in Venice, held at the "Air Conditioned Supper Club."  On the inside, it's a two-room bar with padded walls and a small stage.  AOL, apparently a main sponsor, had a primary spot on stage and was giving out T-shirts, which were catchy but unfortunately made significantly less cool by the non-subtle AOL branding.

We met some interesting people at the event.  There were a number of "showoffs," or companies with small demo booths set up.  One of the attending companies just created this realtime-social-product-browsing-map-thing, and I definitely took the opportunity to ask one of their employees what the feature was all about.  I still don't actually know how it's useful, but apparently it's addictive.  See if you can figure it out.

We saw Heather again, geek dinner organizer and twiistup 2 host.

The event left us with three questions:

  1. What's with the padded walls?
  2. Was I the only person there without an iPhone?
  3. Did we just hang out with Bono, lead-singer of U2?




My entrance interview Two minutes after we stepped in, I was interviewed by Bonny (of NoodleScar fame) while Adam ran away and took this photo.  The inverview touched on the conundrum of the padded walls, whether the microphone actually worked, and whether Adam and I had made it out of the 'garage' at all during the past few weeks.  I was a less than exciting subject, so we'll see if they squeeze anything out of it.

Update: Lan just informed us that the NoodleScar episode is up.  A brief clip of me did make the cut.  Does this mean I can join the SAG?

So, Bono? You be the judge.  We scoured the event's website, and noticed a reference to "surprise guests."  Hmm.  The best evidence we have is the following photo snapped with Adam's camera:

Bono, ono? I'm fairly certain this is fake Bono.  Seriously, the earlobes are off and this guy's chin is a little too dimply.  Adam thinks he's the real deal.  Or at least he was certain until we zoomed in on the ears a little more.  In any case, the host knows, so maybe she'll tell us tomorrow.

We also just noticed that our blog's sweet header somehow scored prime placement on the Twiistup homepage: 

Our logo: bigger than Microsoft and Yahoo combined!

How to consume a WCF service from Perl with SOAP::Lite

Posted by adamjh on Jul 23rd, 2007

Due to the outdated state of Perl's only SOAP library and less-than-stellar documentation on Windows Communication Foundation web service interoperability, getting a Perl script to consume a WCF service sent me on a debugging adventure accompanied by a scavenger hunt for information scattered across the web.

Below are the tweaks that must be made to a new WCF service created using the "WCF Service Library" project template in Visual Studio 2008 Beta 1 ("Orcas") and an example of a how to call the service from a SOAP::Lite client script:

Step 1. Change the service endpoint binding from the default wsHttpBinding to basicHttpBinding:

    <endpoint address ="" binding="basicHttpBinding" contract="Service1.IService1" />

Step 2. Change the data contract format to RPC:

    [ServiceContract]
    [DataContractFormat(Style=OperationFormatStyle.Rpc)]
    public interface IService1
    {

Step 3. Specify an on_action() method in the SOAP::Lite client to override the default Namespace#Action with the format WCF expects:

$data = SOAP::Lite
  -> uri('http://tempuri.org/')
  -> proxy('http://localhost:8080/IService1')
  -> on_action(sub{sprintf '%sIService1/%s', @_})
  -> GetData(SOAP::Data->name('intParam' => 5))->result;

Note: If you decide to do this, you should understand the implications of changing the service endpoint binding and the data contract format.  Supporting information is available somewhere in the bowels of MSDN.

Update [Nov 5 2007]: I ran into new problems when moving from SOAP::Lite 0.55 (the highest supported in ActivePerl on Windows) to SOAP::Lite 0.69 (the latest version as of now, and running on Linux).  It seems SOAP::Lite evolved from the SOAP 1999 (1.1) to 2001 (1.2) schema, and somewhere in the mix, new conflicts arose with WCF interoperability.  After a few hours of horrid tracing and hacking, I've decided to ditch Perl and SOAP altogether for Ruby and REST.  Welcome, Adam, to the year 2007.

Data Access Layer: To LINQ or not to LINQ

Posted by adamjh on Jul 21st, 2007

Over the last several days, our progress meter has leveled off a bit as we've begun to take a step back from rapid prototyping efforts to spend some time thinking through the ways in which components of our system will communicate with each other.

One specific technology, LINQ to SQL (formerly "DLink" and almost certainly to be renamed again before it is released early next year), has particular potential as a drop-in replacement for the traditional data access layer.  DotNetSlackers has a pretty decent introduction, and Kris Vandermotten shares some thoughts on LINQ's implications on the DAL here and here.  He writes:

There is no doubt that Linq to SQL will have an enormous impact on the way we write data access layers. I wouldn’t be surprised to find out that the impact is so profound, that we might even have to reconsider the very nature of a data access layer. In fact, what is a data access layer (DAL) anyway?

Kris's second post concludes that the LINQ/SqlMetal-generated classes might serve as a DAL in and of themselves.  After reading it, I started wondering if/how this might apply to the data access layer we had begun to hack together earlier in the morning.  Jeff and I spent several hours reading, whiteboarding, and discussing whether or not LINQ was ready for "prime time", and if/how we would leverage it in what we're building.

While the idea of not having to design, implement, and maintain a data access layer designed around the needs of our specific system is tempting, a few questions come to mind:

  1. Can LINQ replace the object/relational mapping functionality performed by, and abstraction provided by, the traditional data access layer?
  2. Can instances of the LINQ/SqlMetal-generated easily be passed between components at different tiers?
  3. How does LINQ fit with scaling mechanisms that involve indirection such as data caching and partitioning?
  4. Is there sufficient support for all of the SQL features we're likely to use?
  5. Is it sufficiently performant? (promising early results)

Let's look at question #1.  Traditionally, all of the code that handles queries might have been pushed down into a set of data access methods, libraries, or even services that return data through a set of shared classes or interfaces.  In a simple example, to retrieve information about a user given her email address, I might call a GetUser() method that takes in an email address and returns a User object.  As time progresses, I might realize there is a better way to design my data access layer than exposing hundreds of GetUser()-like methods, and consolidate them by adding more flexible parameters or even by designing a mini-query language myself.  All this data access infrastructure, serving primarily to translate between relational data returned by SQL queries and object data modeled as a set of classes, is time-consuming, and is where I believe LINQ brings significant value.

For example, suppose the component I am working on needs to retrieve information about currently logged-in users.  Using LINQ as a data access mechanism, I could simply code:

        Table<User> users = db.GetTable<User>();

        var q = from u in users
                where u.LoggedIn == true
                select u;
        
        List<User> loggedInUsers = new List<User>(q);

Now, suppose I decide I want to display all the photos of all the currently logged-in users.  Again, using LINQ, with no design/implementation/management overhead around this specific retrieval which joins user and photo data that happens to reside in different tables, I could simply tack-on the following to the above code:

        foreach (var user in loggedInUsers)
        {
            foreach (var photo in user.Photos)
            {
                DisplayPhoto(photo.Data);
            }
        }

In cases where certain specific queries, even as expressed in C#/.Net syntax, are complex and might be reused across the codebase, it still might make sense to extract them out (in their LINQ form).  But the majority overhead of designing, implementing, and maintaining a traditional data access layer is still effectively replaced by the value of LINQ.  So, to sum up my thoughts around question #1, I'd at least say that I'd be willing to explore moving away from the traditional notion of abstracting away queries into a data access "layer", given the value that the LINQ constructs bring to the language/framework.

While question #1 was mostly about buying into vision/value, questions #2-5 are where the rubber hits the road, and are where limitations begin to arise that make us question whether or not LINQ version 1 will meet our needs, as follows:

First, if we are no longer constructing our own set of classes to model data and data retrieval methods to instantiate/populate them, we need to be able to pass LINQ and SqlMetal-generated objects around our n-tier application.  The DataContext is not serializable nor intended to be passed between tiers, and while there is an attach mechanism, support in general for these n-tier scenarios seems to be limited.  Showstopper.

Second, I haven't been able to dig up any strategies or support for introducing indirection into LINQ queries.  If our data is partitioned across many databases, or we need to introduce a cache, I'm unsure how to do this other than wrapping LINQ with well, a data access layer!

Third, I can't seem to find any answers to whether or not LINQ will support some of the newer SQL features like Spatial types/queries, again implying the need for some sort of parallel data access mechanism.

So, to wrap this post up... after roughly a day of investigation, it's safe to say that we've come to the conclusion that while LINQ is a promising technology, and could potentially replace much of the overhead in designing, implementing, and maintaining a data access layer in the future, it's no silver bullet today.  We'll likely incorporate it into our system in some capacity (i.e. as syntactic sugar for querying SQL), but it will likely remain abstracted by a set of data access mechanisms that will still be required for any data that is likely to be cached, partitioned, or accessed by multiple components/tiers now or in the future.

« Prev