Pregunta

Estoy utilizando el control de la firma en OpenNETCF. Funciona muy bien para la mayor parte de todo lo que necesita.

Sin embargo, necesito una manera de invertir la firma y cargarlo de nuevo.

Tiene una llamada para obtener los "bytes" para la firma (GetSignatureEx()). Devuelve un byte[] de la firma. Esta firma puede entonces ser cargado de nuevo con LoadSignatureEx().

Me parece que no puede averiguar el sistema para estos bytes. Pensé que pueden ser las coordenadas, pero no lo parece ahora.

Si alguien por ahí sabe una manera de invertir la firma y cargarlo de nuevo, yo agradecería oírlo.


Nota para otras personas que puedan cuidar:

Estos bytes parecen tener la estructura siguiente (en orden):

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)  

Voy a publicar mi código final, una vez que he hecho.


Más tarde Nota: Bien después de un montón de trabajo, me encontré con lo fácil que es para voltear la vista utilizando el construido en la materia (MusiGenesis gracias). Eso parece ser mucho menos un error de proceso propenso a mí.

Sólo en caso de que alguien más lo quiere, aquí está mi inacabada código. (Yo estaba cerca, pero las cosas para avanzar a la "línea" al lado no funciona del todo bien.) (EDIT:.. Decidí que me ha gustado la forma en que funcionaba un poco más He actualizado el código debajo de ella funcionará siempre que la anchura o altura del control de la firma no es mayor que 256. (Véase la respuesta de ctacke abajo)).

Pero en primer lugar, muchas gracias a MusiGenesis que me ayudaron a entender todo esto. Usted es muy útil y yo apreciamos sus esfuerzos mucho!

Ahora el código:

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;
        }
    }
}
¿Fue útil?

Solución

Completamente-probada de código 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;
            }
        }
    }
}

O intente esta versión, en el supuesto de que los primeros 4 bytes se utilizan para almacenar el ancho y la altura de las firmas (enteros cortos 2 bytes para cada uno):

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

Ver: conversión de OpenNETCF GetSignatureEx de mapa de bits en el escritorio

Actualización: Dada su descripción de por qué es necesario invertir la firma, puede ser que sea más fácil para que usted acaba invertido el screenOrientation de su dispositivo en 180 grados (y luego de nuevo después de los signos de los clientes) . De esta manera también se puede tener etiquetas que indican al cliente lo que está firmando. - de lo contrario van a estar buscando en un montón de cosas al revés (que no sea el propio control de firma)

Para ello, agregue una referencia a Microsoft.WindowsCE.Forms a su proyecto, a continuación, añadir using Microsoft.WindowsCE.Forms; a la parte superior de su archivo.

Para invertir la pantalla 180 grados:

SystemSettings.ScreenOrientation = ScreenOrientation.Angle180;

Para establecer de nuevo a normal:

SystemSettings.ScreenOrientation = ScreenOrientation.Angle0;

Si usted está funcionando esto en el emulador, la pantalla seguirá apareciendo normalmente en posición vertical, pero la piel se volteado al revés.

Actualización: una última oportunidad en esto, basado en la respuesta de ctacke (esto debería funcionar para las firmas con las dimensiones):

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

Otros consejos

Puede ser que sea un poco tarde, pero estoy mirando el código en este momento y aquí están algunos puntos dignos de mención.

  • Los primeros 2 bytes son el ancho.
  • Los siguientes 2 bytes son la altura.
  • El resto de los datos son coordenadas X, Y, sin embargo, el formato de almacenamiento es engañoso y puede cambiar. Si la dimensión (x o y) es <256, se utiliza un byte para almacenar el valor. Si es mayor, se utilizan 2 bytes. Esto significa que usted podría ver valles almacenados como XYXY, XXYXXY o XYYXYY.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top