3

OpenNETCF で Signature コントロールを使用しています。それは私が必要とするほとんどすべてにうまく機能します。

ただし、署名を反転してロードし直す方法が必要です。

署名の「バイト」を取得するための呼び出しがあります ( GetSignatureEx())。byte[]署名の を返します。この署名は、 で再度読み込むことができますLoadSignatureEx()

これらのバイトのシステムを理解できないようです。コーディネートかなと思ったのですが、今は違うようです。

誰かが署名を反転して元に戻す方法を知っている場合は、それを聞いて感謝します.


気にするかもしれない他の人への注意:

これらのバイトは、次の構造を持っているようです (順番に):

幅を示す 2 バイト  
高さを表示する 2 バイト  
  -- この次の部分は配列の最後まで繰り返されます  
  表示する 2 バイト 次の行にいくつのポイントがあるか  
    -- この次の部分は、前の行で示された回数だけ繰り返されます  
    ポイントの x 座標の 1 バイト  
    ポイントの y 座標の 1 バイト  
    ペンの幅は 2 バイト (これについては 100% 確信が持てません)  

完了したら、最終的なコードを投稿します。


後でメモ: たくさんの作業を行った後、組み込みのものを使用してビューを簡単に反転できることがわかりました (MusiGenesis に感謝)。それは私にとってプロセスのエラーが発生しにくいようです。

他の誰かがそれを望んでいる場合に備えて、ここに私の未完成のコードがあります。(私は近くにいましたが、次の「行」に進むためのものがうまく機能しません。) (編集:これがもう少しうまくいく方法が好きだと判断しました。以下のコードを更新しました。署名コントロールの幅または高さが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 の場合、1 バイトを使用して値を格納します。それより大きい場合は、2 バイトを使用します。これは、値が XYXY、XXYXXY、または 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 バイトの short int) を格納するために使用されると仮定して、このバージョンを試してください。

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;

これをエミュレーターで実行している場合、画面は正常に直立して表示されますが、スキンは上下逆になります。

更新:の答え に基づいて、これで最後のショットを1つ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 に答える