Below is information about what Picasa stores as a hash. He stores them as follows:
faces=rect64(54391dc9b6a76c2b),4cd643f64b715489 [DSC_2289.jpg] faces=rect64(1680000a5c26c82),76bc8d8d518750bc
Information on the Internet says this:
The number enclosed in rect64 () is a 64-bit hexadecimal number.
- A break for four 16-bit numbers.
- Divide each by the maximum 16-bit unsigned number (65535), and you will have four digits from 0 to 1.
- The remaining four digits give the relative coordinates for the face rectangle: (left, top, right, bottom).
- If you want to get the absolute coordinates, the image is slightly left and right across the width of the image, and the image height above and below.
So, my code, to turn this into a RectangleF, works just fine (keeping only 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 RectangleF and I want to return it to the hash mentioned above. I can not understand this. It looks like picasa uses 2 bytes, including precision, however the float in C # is 8 bytes and even a bit converter. ToSingle - 4 bytes.
Any help was appreciated.
EDIT: That's 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(); }