Archive for March, 2011

Baidu Maps

Truly impressive: Baidu (“the Google of China”) doesn’t use satellite imagery for its maps, instead it uses isometric, Simcity-style sprites.

Baidu map of Shanghai

It’s beautiful to look at, and with the crystal clear delineation of buildings, roadways, and landmarks, it’s likely a very effective navigational tool as well. The sheer scale of this blows my mind. I can’t even begin to fathom how much time and effort went into creating this much artwork to paint an entire city.

Bing’s bird eye view is the only service I can think of that comes close to this, but is far from impressive at times,

Bing map of Shanghai

h/t ronnestam.com, VisualJournalism

#NewTwitter API

So a few interesting, or rather frustrating things, about the current state of the Twitter API.

I spent way too much time fucking around with a couple of PHP Twitter API libraries to do some automated tweeting. The change late last year of requiring OAuth authentication seems to have left most libraries broken. TwitterOAuth seemed to support OAuth and I saw it mentioned in a couple of blog posts, so I gave it a try. It seemed to work well and I got the access tokens, but subsequent requests resulted in a “Incorrect signature” error. So I used the Twitter class by Tijs Verkoyen, which did the trick.

With the new web client supporting media attach to tweets, I figured surely there must be some way to do this from the API. There isn’t. Only content from one of Twitter’s media partners is attached. The term “media partners” should have probably been a red flag to developers regarding the shape of things to come. To add insult to injury, the client-side code for this is ridiculously easy to extend (creating a new twttr.mediaType).

Finally, the recent announcement with Twitter coming out against third-party clients. I can’t say I’m surprised at all, especially as Twitter moves further towards selling ads and actually making a profit, for which they’ll need tighter control. Why third-party clients were allowed in the first place is questionable beyond it being a bait-and-switch tactic to lure developers and users. Personally, I use the web client, so I don’t care that much as a user and my recent development efforts have just revolved around server-side tweeting, so I don’t care that much as a developer, but to those burned I’d say suck it up and learn from it. Twitter, Facebook, bit.ly, whoever… pretty much every company out, they doesn’t make an API for your sake, but for theirs. Invest too much time, energy, and/or money and your almost definitely going suffer disappointment and betrayal. If your project is important to you, be ready to pull the plug and build your own platform or ecosystem; use them, don’t let them use you.

progTools 1.7

Another update to progTools. Ignore the jump in version number, that’s a result of fighting with the Air ApplicationUpdater.

New features:

  • Auto-update
  • Encode/Decode URI
  • Escape string
  • Encode/Decode HTML special entities
  • Text character and word counter
Please upgrade your Flash Player This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed.

progTools 1.7

Better Checkboxes

Another take on styling checkboxes with jQuery+CSS by Martin Angelov.

Better Check Boxes with jQuery and CSS by Martin Angelov

I’m not sure if they should really be called checkboxes at this point. I did something very similar a while ago, I called them toggle buttons.

Quake 3

I have a bunch of old video game magazines I’m sorting through. I love the old issues of PC Gamer and it’s awesome to see some of the old ads and articles. Here’s a gem from the September 1999 issue:

quake 3 ad from Sept. 1999 issue of PC Gamer

I didn’t play Quake 3 until well after release, as the case is with most games I play, but for Quake 3 in particular I couldn’t play it until I got a Voodoo 3 as it required 3d hardware acceleration. I didn’t play online much, but I had a blast playing thru the single-player tiers. That said, I was disappointed with the lack of CTF, the dialog from the bots seemed stupid (attempting and failing badly to mimic how players talked online), and the lack of variety in level design was disappointing (transitioning only between the tech arenas and the hellish, fog-filled ones)… perhaps not an issue in multiplayer, but in single-player, the maps took a front seat to your soulless opponents. A solid game and great deathmatch experience nonetheless, but I remember playing Unreal Tournament much more, both online and off.

dotspott notes + submenu design update

Two very minor updates to the dotspott web client:

  • Sticky note icons now appears when a note is attached to a spott. Clicking the icon will bring up a dialog with the note.
  • Spott submenus are now made to look more like buttons and spaced a bit further down from the tag list.

spott with sticky icon and new submenu

Flexible Binary Format

Another project I worked on a long time ago but never released. The goal of Flexible Binary Format was to create a file format and library for dealing with (tree) structured binary data (in the same vein of what XML does for textual data). This was a reaction both to the verbose and non-binary-friendly nature of XML and to the ugly chunk-based structuring done in many binary file formats.

The code for the C++ library is now up.

I’ll do a high-level, quick-and-dirty tutorial in this post to show how things work.


include FBF.h

#include "FBF.h"


Build a data tree

FlexibleBinaryFormat::DataTree        dt;
FlexibleBinaryFormat::TreeBuilder    dataTreeBuilder(&dt);


Attach a node to the data tree

dataTreeBuilder.AttachNode("root/vertex");


Make a vector of nodes and sub-nodes

dataTreeBuilder.AttachNode("root/vertex");
dataTreeBuilder.AttachNode(
"root/vertex");
dataTreeBuilder.AttachNode("root/vertex[0]/xyz");
dataTreeBuilder.AttachNode(
"root/vertex[1]/abc");

Note: We created 2 nodes on the same path (root/vertex). We access them individually using an index number within brackets.


Attach data to nodes

dataTreeBuilder.AttachDouble("root/vertex[0]/xyz", 0.12345);
dataTreeBuilder.AttachDouble(
"root/vertex[1]/abc", 54321.0);

Once data is attached to a node, you can’t attach a sub-node to it.
(i.e. data is stored on the leaves of the data tree)

The following methods of FlexibleBinaryFormat::TreeBuilder are available to attach data to a node:

  • AttachString()
  • AttachBool()
  • AttachByte()
  • AttachSByte()
  • AttachDouble()
  • AttachFloat()
  • AttachShort()
  • AttachUShort()
  • AttachInt()
  • AttachUInt()
  • AttachInt()
  • AttachUInt()
  • AttachLong()
  • AttachULong()


Write the data tree out to a file

FlexibleBinaryFormat::FlexibleIO    flexio(&dt);
flexio.WriteToFile(
"test.fbf");


Read a data tree from a file

FlexibleBinaryFormat::DataTree        dt2;
FlexibleBinaryFormat::FlexibleIO    flexio2(&dt2);
flexio2.ReadFromFile(
"test.fbf");


Read data from a node

double v0xyz = dt2.GetData<double>("root/vertex[0]/xyz", 0);
// second arg is always 0;
// arg is a leftover from some deprecated stuff in older versions and will be removed

progTools 1.3

An update to progTools is now available.

New features and fixes:

  • Corrected ISO-8601 timestamp format
  • Added MySQL timestamp format
  • Base64 encoding and decoding
  • File to data URI generator
Please upgrade your Flash Player This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed.

progTools 1.3

TransparencyExtract

A long while ago, I wrote a post on a method to extract transparency from images with solid-colored backgrounds, and somewhat effectively reduce the halo effect around objects in the image. I never got around to releasing the code or application, which I’m finally doing now.

All code + app is here.
It’s in C# + WinForms, and I put the entire VS solution in the bitbucket repo.

TransparencyExtract app

The guts of it all is the PerformExtraction() function in TransparencyExtract.cs

public void PerformExtraction()
{
ColorF bgColorF = new ColorF(backgroundColor);
ColorF fgColorF = new ColorF(foregroundColor);
float backL = bgColorF.L();
float foreL = fgColorF.L();

float minL = Math.Min(backL, foreL);
float deltaL = Math.Max(backL, foreL) - minL;


newBitmap =
new Bitmap(srcBmp.Width, srcBmp.Height, PixelFormat.Format32bppArgb);

BitmapData bdDest = newBitmap.LockBits(new Rectangle(0, 0, newBitmap.Width, newBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, newBitmap.PixelFormat);
IntPtr ptrDest = bdDest.Scan0;

BitmapData bd = srcBmp.LockBits(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, srcBmp.PixelFormat);
IntPtr ptr = bd.Scan0;

int bpp = 4;
int bytes = srcBmp.Height * bd.Stride;
byte[] rgbValues = new byte[bytes];
byte[] rgbValuesDest = new byte[bytes];
System.Runtime.InteropServices.
Marshal.Copy(ptr, rgbValues, 0, bytes);
System.Runtime.InteropServices.
Marshal.Copy(ptrDest, rgbValuesDest, 0, bytes);

Array.Copy(rgbValues, rgbValuesDest, rgbValues.Length);

for (int y = 0; y < srcBmp.Height; y++)
{
for (int x = 0; x < srcBmp.Width; x++)
{
int idx = (x * bpp + y * bd.Stride);

ColorF cf = new ColorF(Color.FromArgb(rgbValues[idx + 3], rgbValues[idx + 2], rgbValues[idx + 1], rgbValues[idx]));

// scale from [minL, 1] -> [0,1]
float scaleUpCoeff = 1.0f / deltaL;
float ld = (cf.L() - minL) * scaleUpCoeff;

if (ld > 1.0f)
ld = 1.0f;

if (ld < 0.0f)
ld = 0.0f;

float alpha = 1.0f - ld;

rgbValuesDest[idx+3] = (
byte)(alpha * 255.0f); // this is the alpha
}
}

System.Runtime.InteropServices.
Marshal.Copy(rgbValues, 0, ptr, bytes);
System.Runtime.InteropServices.
Marshal.Copy(rgbValuesDest, 0, ptrDest, bytes);

srcBmp.UnlockBits(bd);
newBitmap.UnlockBits(bdDest);
}

Note, this is not a generic algorithm by any means; read my original post to understand what’s going on and the limitations of this method.