3

我在 OpenNETCF 中使用 Signature 控件。它适用于我需要的大多数东西。

但是,我需要一种方法来反转签名并将其重新加载。

它有一个调用来获取签名(GetSignatureEx())的“字节”。它返回一个byte[]签名。然后可以使用LoadSignatureEx().

我似乎无法弄清楚这些字节的系统。我以为它们可能是坐标,但现在似乎不是。

如果那里有人知道反转签名并将其重新加载的方法,我将不胜感激。


其他可能关心的人请注意:

这些字节似乎具有以下结构(按顺序):

2 个字节显示宽度  
2 个字节显示高度  
  -- 下一部分重复到数组的末尾  
  2 个字节显示下一行有多少个点  
    -- 下一部分重复上一行指示的次数  
    1 个字节用于点的 x 坐标  
    1 个字节用于点的 y 坐标  
    2 个字节表示笔的宽度(我不是 100% 确定这个)  

完成后,我将发布我的最终代码。


后来注意:好的,经过大量工作,我发现使用内置的东西翻转视图是多么容易(感谢MusiGenesis)。对我来说,这似乎是一个不太容易出错的过程。

以防万一其他人想要它,这是我未完成的代码。(我很接近,但推进到下一个“行”的东西不太正确。) (编辑:我决定我更喜欢这种工作方式。我已经更新了下面的代码。只要 Signature 控件的宽度或高度不大于 256,它就可以工作。(见下面 ctacke 的回答)。 )

但首先,非常感谢 MusiGenesis 帮助我解决了这一切。你很有帮助,我非常感谢你的努力!

现在代码:

private void InvertSignature(ref byte[] original)
{
    int currentIndex = 0;
    short width = BitConverter.ToInt16(original, 0);
    short height = BitConverter.ToInt16(original, 2);
    while (currentIndex < original.Length - 4)
    {
        // Move past the last iteration (or the width and hight for the first time through).
        currentIndex += 4;
        // Find the length of the next segment.
        short nextGroup = BitConverter.ToInt16(original, currentIndex);
        //Advance one so we get past the 2 byte group
        currentIndex += 2;
        // Find the actual index of the last set of coordinates for this segment.
        int nextNumberOfItems = ((nextGroup) * 4) + currentIndex;
        // Invert the coordinates
        for (int i = currentIndex; i < (nextNumberOfItems - 1); i += 4)
        {
            currentIndex = i;

            //Invert Horizontal
            int newHorzPoint = width - original[i] - 1;
            if (newHorzPoint <= 0)
                newHorzPoint = 0;
            else if (newHorzPoint >= width - 1)
                newHorzPoint = width - 1;
            original[i] = (byte)newHorzPoint;

            // Invert Vertical
            int newVertPoint = height - original[i + 1] - 1;
            if (newVertPoint <= 0)
                newVertPoint = 0;
            else if (newVertPoint >= height - 1)
                newVertPoint = height - 1;
            original[i + 1] = (byte)newVertPoint;
        }
    }
}
4

2 回答 2

3

我可能有点晚了,但我现在正在查看代码,这里有一些值得注意的点。

  • 前 2 个字节是宽度。
  • 接下来的 2 个字节是高度。
  • 其余数据是 X、Y 坐标,但是存储格式具有欺骗性,并且可以更改。如果维度(x 或 y)<256,我们使用一个字节来存储值。如果它更大,我们使用 2 个字节。这意味着您可能会看到存储为 XYXY、XXXXXY 或 XYYXYY 的值。
于 2010-04-19T13:26:53.963 回答
2

完全未经测试的代码高尔夫:

public void InvertSignature(ref byte[] original, 
    bool invertHorizontal, bool invertVertical)
{
    for (int i = 0; i < original.Length; i += 2)
    {
        if ((original[i] != 0) && (original[i + 1] != 0))
        {
            if (invertHorizontal)
            {
                original[i] = 232 - original[i] - 1;
            }
            if (invertVertical)
            {
                original[i + 1] = 64 - original[i + 1] - 1;
            }
        }
    }
}

或者试试这个版本,假设前 4 个字节用于存储签名的宽度和高度(每个 2 字节短整数):

public void InvertSignature(ref byte[] original, 
    bool invertHorizontal, bool invertVertical)
{
    byte w = (byte)BitConverter.ToInt16(original, 0) - 1;
    byte h = (byte)BitConverter.ToInt16(original, 2) - 1;
    // TO DO: blow up if w or h are > 255
    for (int i = 4; i < original.Length; i += 2)
    {
        if ((original[i] != 0) && (original[i + 1] != 0))
        {
            if (invertHorizontal)
            {
                original[i] = w - original[i];
            }
            if (invertVertical)
            {
                original[i + 1] = h - original[i + 1];
            }
        }
    }
}

请参阅: 将 OpenNetCF GetSignatureEx 转换为桌面上的位图

更新: 鉴于您对为什么需要反转签名的描述,您可能更容易将设备的 ScreenOrientation 反转 180 度(然后在客户签名后返回)。通过这种方式,您还可以使用标签告诉客户他们正在签署什么 - 否则他们将看到一堆颠倒的东西(除了签名控制本身)。

为此,请添加对Microsoft.WindowsCE.Forms项目的引用,然后添加using Microsoft.WindowsCE.Forms;到文件顶部。

要将屏幕反转 180 度:

SystemSettings.ScreenOrientation = ScreenOrientation.Angle180;

要恢复正常:

SystemSettings.ScreenOrientation = ScreenOrientation.Angle0;

如果您在模拟器中运行它,您的屏幕仍将正常显示为直立,但皮肤会上下翻转。

更新: 最后一枪,基于ctacke的回答(这应该适用于任何尺寸的签名):

public void InvertSignature(ref byte[] original, 
    bool invertHorizontal, bool invertVertical)
{
    short w = BitConverter.ToInt16(original, 0);
    short h = BitConverter.ToInt16(original, 2);
    int i = 4;
    while (i < original.Length)
    {
        if (invertHorizontal)
        {
            if (w < 256)
            {
                if (original[i] != 0)
                {
                    original[i] = (byte)w - original[i] - 1;
                }
                i++;
            }
            else
            {
                short val = BitConverter.ToInt16(original, i);
                if (val != 0)
                {
                    val = w - val - 1;
                    byte[] valbytes = BitConverter.GetBytes(val);
                    Buffer.BlockCopy(valbytes, 0, original, i, 2);
                }
                i += 2;
            }
        }
        else
        {
            i += (w < 256) ? 1 : 2;
        }
        if (invertVertical)
        {
            if (h < 256)
            {
                if (original[i] != 0)
                {
                    original[i] = (byte)h - original[i] - 1;
                }
                i++;
            }
            else
            {
                short val = BitConverter.ToInt16(original, i);
                if (val != 0)
                {
                    val = h - val - 1;
                    byte[] valbytes = BitConverter.GetBytes(val);
                    Buffer.BlockCopy(valbytes, 0, original, i, 2);
                }
                i += 2;
            }
        }
        else
        {
            i += (h < 256) ? 1 : 2;
        }
    }
}
于 2010-04-17T06:49:31.780 回答