سؤال

فيما يلي تفاصيل ما هي مخازن بيكاسا باعتباره التجزئة. يخزنها مثل هذا:

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

معلومات حول الويب تقول هذا:

الرقم الموضح في REST64 () هو رقم سداسي عشري 64 بت.

  • كسر ذلك إلى أربعة أرقام 16 بت.
  • قم بتقسيم كل كحد أقصى رقم 16 بت غير موقعة (65535) ولديه أربع أرقام بين 0 و 1.
  • الأرقام الأربعة المتبقية تعطيك الإحداثيات النسبية لمستطيل الوجه: (يسار، أعلى، يمين، أسفل).
  • إذا كنت ترغب في الانتهاء من الإحداثيات المطلقة، فإن العديد من الأيسر واليمين من خلال عرض الصورة والأعلى والأسفل بواسطة ارتفاع الصورة.

لذلك فإن التعليمات البرمجية لتحويل ذلك إلى مستطيل يعمل بشكل جيد فقط (حفظ الإحداثيات النسبية فقط):

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

الآن لدي مستطيل وأريد تحويله إلى التجزئة المذكورة أعلاه. لا أستطيع أن يبدو أن معرفة ذلك. يبدو أن Picasa يستخدم 2 بايت بما في ذلك الدقة، ولكن تعويم في C # هو 8 بايت، وحتى bitconverter.toutingle هو 4 بايت.

أي مساعدة موضع تقدير.

تحرير: هنا هو ما لدي الآن

    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();
    }
هل كانت مفيدة؟

المحلول

يعد الرمز الحالي الخاص بك بايت من كل تنسيق. وذلك لأن BitConverter يمنحك البايتات في طلب نبيذ صغير (أي البايت الأول في الصفيف هو الأقل أهمية بايت). المبادلة حول مهامك على النحو التالي يجعل فك تشفير وإعادة الترميز تعيد التجزئة الأصلية.

        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];

ومع ذلك، أعتقد أن الأمر أكثر وضوحا للقيام بالتحويل باستخدام تضاعف بسيط ويضيف. يمكنك القيام بشيء مماثل مع فك ترتيب سلسلة التجزئة إذا قرأته كواحد ulong وطرح / تقسيم. على سبيل المثال بالنسبة للترميز:

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

نصائح أخرى

يبدو أنك بحاجة إلى إخراج أنواع تعويم من hashfromrectoangle (rect) مثل ذلك:

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

أيضا، قد يكون ذلك أكثر قابلية للقراءة لاستخدام هذا لملء الصفيف:

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

دعني اعرف اذا هذه تعمل!

هارون

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top