简体   繁体   English

OpenNETCF签名控制问题

[英]OpenNETCF Signature control question

I am using the Signature control in OpenNETCF. 我在OpenNETCF中使用Signature控件。 It works great for most everything I need. 它适用于我需要的大多数东西。

However, I need a way invert the signature and load it back in. 但是,我需要一种方法来反转签名并将其加载回来。

It has a call to get the "bytes" for the signature ( GetSignatureEx() ). 它有一个调用来获取签名的“字节”( GetSignatureEx() )。 It returns a byte[] of the signature. 它返回签名的byte[] This signature can then be loaded back in with LoadSignatureEx() . 然后可以使用LoadSignatureEx()重新加载此签名。

I can't seem to figure out the system for these bytes. 我似乎无法弄清楚这些字节的系统。 I thought they may be coordinates, but it does not seem so now. 我认为它们可能是坐标,但现在看来并不是这样。

If anyone out there knows a way to invert the signature and load it back in, I would be grateful to hear it. 如果有人在那里知道一种方法来反转签名并重新加载,我将很高兴听到它。


Note for others who may care: 其他可能关心的人请注意:

These bytes seem to have the following structure (in order): 这些字节似乎具有以下结构(按顺序):

2 bytes to show Width  
2 bytes to show Height  
  -- This next part repeats till the end of the array  
  2 bytes to show How many points are in the next line  
    -- This next part repeats as many times as the previous line indicated  
    1 byte for the x coordinate of the point  
    1 byte for the y coordinate of the point  
    2 bytes for the width of the pen (I am not 100% sure on this one)

I will post my final code once I have it done. 完成后我会发布我的最终代码。


Later Note: Ok after tons of work, I found how easy it is to flip the view using the built in stuff (thanks MusiGenesis). 后来注意:经过大量的工作,我发现使用内置的东西翻转视图是多么容易(感谢MusiGenesis)。 That seems to be way less error prone a process to me. 这对我来说似乎不那么容易出错。

Just in case someone else wants it, here is my unfinished code. 以防其他人想要它,这是我未完成的代码。 (I was close but the stuff to advance to the next "line" does not work quite right.) (我很接近,但推进到下一个“线”的东西不能正常工作。) (EDIT: I decided that I liked the way this worked a bit more. I have updated the code below. It will work as long as the width or height of the Signature control is not greater than 256. (See ctacke's answer below).) (编辑:我决定我更喜欢它的工作方式。我已经更新了下面的代码。只要Signature控件的宽度或高度不大于256,它就会工作。(参见下面的ctacke答案)。 )

But first, big thanks to MusiGenesis who helped me figure all this out. 但首先,非常感谢MusiGenesis帮我解决了这一切。 You are very helpful and I appreciate your efforts a lot! 您非常乐于助人,我非常感谢您的努力!

Now the code: 现在的代码:

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

I might be a little late, but I'm looking at the code right now and here are some points worth noting. 我可能有点晚了,但我现在正在看代码,这里有一些值得注意的地方。

  • The first 2 bytes are the width. 前2个字节是宽度。
  • The next 2 bytes are the Height. 接下来的2个字节是高度。
  • The remainder of the data are X,Y coordinates, however the storage format is deceptive and it can change. 其余数据是X,Y坐标,但存储格式具有欺骗性,可以更改。 If the dimension (x or y) is < 256, we use one byte to store the value. 如果维度(x或y)<256,我们使用一个字节来存储该值。 If it's greater, we use 2 bytes. 如果它更大,我们使用2个字节。 This means you might see vales stored as XYXY, XXYXXY or XYYXYY. 这意味着您可能会看到存储为XYXY,XXYXXY或XYYXYY的值。

Completely-untested-code Golf: 完全未经测试的代码高尔夫:

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

Or try this version, on the assumption that the first 4 bytes are used to store the width and height of the signature (2 byte short ints for each): 或者尝试这个版本,假设前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];
            }
        }
    }
}

See: Converting OpenNetCF GetSignatureEx to Bitmap on Desktop 请参阅: 将OpenNetCF GetSignatureEx转换为桌面上的位图

Update: Given your description of why you need to invert the signature, it might be easier for you to just invert the ScreenOrientation of your device by 180 degrees (and then back after the customer signs). 更新:鉴于您对需要反转签名的描述,您可能更容易将设备的ScreenOrientation反转180度(然后在客户签名后返回)。 This way you could also have labels that tell the customer what they're signing - otherwise they're going to be looking at a bunch of upside-down stuff (other than the signature control itself). 通过这种方式,您还可以使用标签告诉客户他们正在签署什么 - 否则他们将会看到一堆颠倒的东西(除了签名控件本身)。

To do this, add a reference to Microsoft.WindowsCE.Forms to your project, then add using Microsoft.WindowsCE.Forms; 为此,请将Microsoft.WindowsCE.Forms的引用添加到项目中,然后using Microsoft.WindowsCE.Forms;添加using Microsoft.WindowsCE.Forms; to the top of your file. 到文件的顶部。

To invert the screen by 180 degrees: 将屏幕反转180度:

SystemSettings.ScreenOrientation = ScreenOrientation.Angle180;

To set back to normal: 要恢复正常:

SystemSettings.ScreenOrientation = ScreenOrientation.Angle0;

If you're running this in the emulator, your screen will still appear normally upright, but the skin gets flipped upside-down. 如果你在模拟器中运行它,你的屏幕仍然会正常显示,但皮肤会颠倒翻转。

Update: one last shot at this, based on ctacke 's answer (this should work for signatures with any dimensions): 更新:根据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;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM