我在OpenNETCF中使用Signature控件。它适用于我需要的大多数东西。
但是,我需要一种方法来反转签名并将其加载回来。
它有一个调用来获取签名的“字节”(GetSignatureEx()
)。它返回签名的byte[]
。然后可以使用LoadSignatureEx()
重新加载此签名。
我似乎无法弄清楚这些字节的系统。我认为它们可能是坐标,但现在看来并不是这样。
如果有人在那里知道一种方法来反转签名并重新加载,我将很高兴听到它。
注意其他可能关心的人:
这些字节似乎具有以下结构(按顺序):
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)
我完成后会发布最终代码。
稍后注意: 经过大量的工作,我发现使用内置的东西翻转视图是多么容易(感谢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;
}
}
}
答案 0 :(得分:3)
我可能会有点迟到,但我现在正在看代码,这里有一些值得注意的地方。
答案 1 :(得分: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];
}
}
}
}
请参阅:Converting OpenNetCF GetSignatureEx to Bitmap on Desktop
更新:鉴于您对需要反转签名的描述,您可能更容易将设备的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;
}
}
}