Question

Voici les détails pour ce que les magasins Picasa une table de hachage. Il les stocke comme ceci:

faces=rect64(54391dc9b6a76c2b),4cd643f64b715489
[DSC_2289.jpg]
faces=rect64(1680000a5c26c82),76bc8d8d518750bc

Infos sur le web dit ceci:

Le nombre enfermé dans rect64 () est un nombre hexadécimal 64 bits.

  • break qui en quatre numéros 16 bits.
  • Diviser chaque par le non signé Nombre maximal de 16 bits (65535) et vous aurez quatre nombres compris entre 0 et 1.
  • Les quatre autres chiffres vous donner les coordonnées relatives pour le rectangle du visage:. (Gauche, haut, droite, bas)
  • Si vous voulez retrouver avec des coordonnées absolues, multiple gauche et à droite par la largeur de l'image et le haut et le bas par la hauteur de l'image.

Alors mon code pour le transformer en un RectangleF fonctionne très bien (seulement garder les coordonnées relatives):

    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);
    }

J'ai maintenant RectangleF et je veux le remettre dans le hachage mentionné ci-dessus. Je ne peux pas sembler comprendre. Il ressemble picasa utilise 2 octets, y compris la précision, mais un flotteur en C # est de 8 octets, et même BitConverter.ToSingle est de 4 octets.

Toute aide appréciée.

EDIT: Voici ce que j'ai en ce moment

    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();
    }
Était-ce utile?

La solution

Votre code actuel est permutant les octets de chaque coordonnée. En effet, BitConverter vous donne les octets dans peu d'ordre endian (à savoir le premier octet dans le tableau est le moins significatif octet). Permutation autour de vos missions comme suit fait le décodage et réencodage rendre le hachage d'origine.

        barray[0] = lb[1];
        barray[1] = lb[0];
        barray[2] = tb[1];
        barray[3] = tb[0];
        barray[4] = rb[1];
        barray[5] = rb[0];
        barray[6] = bb[1];
        barray[7] = bb[0];

Cela dit, je pense qu'il est plus clair pour faire la conversion à l'aide de simples et ajoute multiplications. Vous pouvez faire la même chose avec le décodage de la chaîne de hachage si vous lisez dans comme un seul ulong et soustrayez / fracture. par exemple. pour le codage:

    public static ushort ToUShort(double coordinate)
    {
        double ratio = Math.Max(0, Math.Min(Math.Round(coordinate * 65535), 65535));
        return (ushort)ratio;
    }

    public static string HashFromRectangle(Rect rect)
    {
        ulong left = ToUShort(rect.Left);
        ulong top = ToUShort(rect.Top);
        ulong right = ToUShort(rect.Right);
        ulong bottom = ToUShort(rect.Bottom);

        ulong hash = (((left * 65536) + top) * 65536 + right) * 65536 + bottom;
        return hash.ToString("x");
    }

Autres conseils

Il semble que vous devez prendre les types de flotteur de HashFromRectangle (rect) comme ceci:

    UInt16 left = (UInt16)( rect.Left * 65535.0F);
    UInt16 top =(UInt16) (rect.Top * 65535.0F);
    UInt16 right = (UInt16) (rect.Right * 65535.0F);
    UInt16 bottom = (UInt16) (rect.Bottom * 65535.0F);

En outre, il est peut-être plus lisible à utiliser pour remplir le tableau:

    Array.Copy(lb, 0, barray, 0, 2);
    Array.Copy(tb, 0, barray, 2, 2);
    Array.Copy(rb, 0, barray, 4, 2);
    Array.Copy(bb, 0, barray, 6, 2);

Faites-moi savoir si cela fonctionne!

Aaron

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top