Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将矩形反转为Picasa面哈希_C#_Picasa_Bitconverter - Fatal编程技术网

C# 如何将矩形反转为Picasa面哈希

C# 如何将矩形反转为Picasa面哈希,c#,picasa,bitconverter,C#,Picasa,Bitconverter,以下是Picasa作为散列存储的内容的详细信息。它像这样存储它们: faces=rect64(54391dc9b6a76c2b),4cd643f64b715489 [DSC_2289.jpg] faces=rect64(1680000a5c26c82),76bc8d8d518750bc 网上的信息说: 包含在rect64()中的数字是64位十六进制数 将其分解为四个16位数字 将每个数字除以最大无符号16位数字(65535),将得到四个介于0和1之间的数字 剩下的四个数字为您提供了面矩形的相

以下是Picasa作为散列存储的内容的详细信息。它像这样存储它们:

faces=rect64(54391dc9b6a76c2b),4cd643f64b715489
[DSC_2289.jpg]
faces=rect64(1680000a5c26c82),76bc8d8d518750bc
网上的信息说:

包含在rect64()中的数字是64位十六进制数

  • 将其分解为四个16位数字
  • 将每个数字除以最大无符号16位数字(65535),将得到四个介于0和1之间的数字
  • 剩下的四个数字为您提供了面矩形的相对坐标:(左、上、右、下)
  • 如果希望以绝对坐标结束,请将左侧和右侧乘以图像宽度,将顶部和底部乘以图像高度
因此,我将其转换为矩形F的代码运行良好(仅保持相对坐标):

现在我有一个矩形,我想把它转换回上面提到的散列。我似乎无法理解这一点。看起来picasa使用了包括精度在内的2个字节,但是C#中的浮点是8个字节,甚至BitConverter.ToSingle也是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();
    }

看起来您需要从HashFromRectangle(rect)中取出浮点类型,如下所示:

此外,使用此选项填充数组可能更具可读性:

    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);
让我知道这是否有效


Aaron

您当前的代码正在交换每个坐标的字节。这是因为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
读入并进行减法/除法,则可以对其进行类似的解码。e、 g.对于编码:

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

由于没有2字节的浮点数据类型(在C#中),您可以尝试将其转换为短数据类型。转换必须是显式的(),否则编译器会抛出一个错误。我也试过了,但我的哈希结果却不尽相同。我在上面发布我的代码,看看我是否做了一些明显错误的事情。不幸的是没有。我在已知的1cf0102160008916散列上测试了这个。结果是散列ff2983393f520976并反转到错误的坐标。谢谢,它似乎失去了一点精度,但这是正确的。
        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];
    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");
    }