Here are the details for what Picasa stores as a hash. It stores them like this:
faces=rect64(54391dc9b6a76c2b),4cd643f64b715489
[DSC_2289.jpg]
faces=rect64(1680000a5c26c82),76bc8d8d518750bc
Info on the web says this:
The number encased in rect64() is a 64-bit hexadecimal number.
- Break that up into four 16-bit numbers.
- Divide each by the maximum unsigned 16-bit number (65535) and you'll have four numbers between 0 and 1.
- The four numbers remaining give you relative coordinates for the face rectangle: (left, top, right, bottom).
- If you want to end up with absolute coordinates, multiple the left and right by the image width and the top and bottom by the image height.
So my code to turn that into a RectangleF works just fine (only keeping relative coordinates):
public static RectangleF GetRectangle(string hashstr)
{
UInt64 hash = UInt64.Parse(hashstr, System.Globalization.NumberStyles.HexNumber);
byte[] bytes = BitConverter.GetBytes(hash);
UInt16 l16 = BitConverter.ToUInt16(bytes, 6);
UInt16 t16 = BitConverter.ToUInt16(bytes, 4);
UInt16 r16 = BitConverter.ToUInt16(bytes, 2);
UInt16 b16 = BitConverter.ToUInt16(bytes, 0);
float left = l16 / 65535.0F;
float top = t16 / 65535.0F;
float right = r16 / 65535.0F;
float bottom = b16 / 65535.0F;
return new RectangleF(left, top, right - left, bottom - top);
}
Now I have a RectangleF and I want to turn it back into the hash mentioned above. I can't seem to figure this out. It looks like picasa uses 2 bytes including precision, however a float in C# is 8 bytes, and even BitConverter.ToSingle is 4 bytes.
Any help appreciated.
EDIT: Here is what I have right now
public static string HashFromRectangle(RectangleCoordinates rect)
{
Console.WriteLine("{0} {1} {2} {3}", rect.Left, rect.Top, rect.Right, rect.Bottom);
UInt16 left = Convert.ToUInt16((float)rect.Left * 65535.0F);
UInt16 top = Convert.ToUInt16((float)rect.Top * 65535.0F);
UInt16 right = Convert.ToUInt16((float)rect.Right * 65535.0F);
UInt16 bottom = Convert.ToUInt16((float)rect.Bottom * 65535.0F);
byte[] lb = BitConverter.GetBytes(left);
byte[] tb = BitConverter.GetBytes(top);
byte[] rb = BitConverter.GetBytes(right);
byte[] bb = BitConverter.GetBytes(bottom);
byte[] barray = new byte[8];
barray[0] = lb[0];
barray[1] = lb[1];
barray[2] = tb[0];
barray[3] = tb[1];
barray[4] = rb[0];
barray[5] = rb[1];
barray[6] = bb[0];
barray[7] = bb[1];
return BitConverter.ToString(barray).Replace("-", "").ToLower();
}