Vb.net 将签名位图转换为签名字符串(非常奇怪)

Vb.net 将签名位图转换为签名字符串(非常奇怪),vb.net,image,graphics,bitmap,Vb.net,Image,Graphics,Bitmap,基本上,我需要将位图图像转换为字符串,但它不是一个常见的字符串 困境在于该字符串由两部分组成: 1) 要点 2) 线条 我需要将图像转换为由*分隔的两部分 我得到的一个例子是: "221A*221A270A270A2503250320072007171617160D2A0D2A07380738073F073F0B3E0B3E15311531222122212C182C183016301631173117311A311A302230222E272E272D2C2D2C2C2F2C2F2C312C3

基本上,我需要将位图图像转换为字符串,但它不是一个常见的字符串

困境在于该字符串由两部分组成:

1) 要点 2) 线条

我需要将图像转换为由*分隔的两部分

我得到的一个例子是:

"221A*221A270A270A2503250320072007171617160D2A0D2A07380738073F073F0B3E0B3E15311531222122212C182C183016301631173117311A311A302230222E272E272D2C2D2C2C2F2C2F2C312C312C2F2C2F2E2B2E2B3126312633223322371D371D381C381C3B1B3B1B3C1C3C1C3D1F3D1F3D243D243C2D3C2D3A333A333A363A36393939393B383B383D363D36412E412E46264626492049204B1B4B1B4E184E184F174F175017501751185118511D511D51225122502450244F294F294F2C4F2C4E2F4E2F4F314F315030503052305230552C552C582958295D225D22601E601E611C611C621B621B621A621A601A601A5D1B5D1B5B1E5B1E5723572353285328512B512B502E502E502F502F513151315231523154305430582E582E592D592D5C2C5C2C5F2A5F2A6428642865286528692669266D246D247122712275207520791D791D7D1B7D1B81198119841884188618861887198719881A881A891B891B881C881C871E871E861F861F852085208421842182228222812481247F257F257E257E257D257D257C247C247C217C217D1F7D1F7E1C7E1C801A801A81198119821782178317831784188418851A851A851C851C86208620862286228625862587278727872B872B882E882E893289328A338A338E348E349033903393329332972F972F9A2D9A2D9F299F29A426A426AB20AB20AF1CAF1CB517B517B716B716B716"
所以我只知道221A是点,另一根弦是线,但需要能够做到这一点

你们谁以前见过这个

我曾尝试将位图转换为Base64String,但这并没有给我任何帮助

如果有帮助,我在VB中只有相反的选项,即从字符串到图像:

Private Sub unpackBMP(ByVal BITMAP As String)
Dim points As String
Dim lines As String
Dim x As Long
Dim y As Long
Dim x1 As Long
Dim y1 As Long

points = firstItem(BITMAP, "*")
lines = BITMAP


While Len(points) > 0

x = "&H" & Mid(points, 1, 2)
y = "&H" & Mid(points, 3, 2)
points = Mid(points, 5, Len(points) - 4)

'picDraw.PSet (Val(x), Val(y)), vbBlack
'Call picDraw.DrawPoint(CDbl(x), CDbl(y))
'picDraw.Refresh
Wend


While Len(lines) > 0

x = "&H" & Mid(lines, 1, 2)
y = "&H" & Mid(lines, 3, 2)
x1 = "&H" & Mid(lines, 5, 2)
y1 = "&H" & Mid(lines, 7, 2)

lines = Mid(lines, 9, Len(lines) - 8)

'picDraw.Line (Val(x), Val(y))-(Val(x1), Val(y1)), vbBlack
'Call picDraw.DrawLine(CDbl(x), CDbl(y), CDbl(x1), CDbl(y1), 0)
'picDraw.Refresh
Wend

'Call picDraw.DrawLine(lines(1, tmp), lines(2, tmp), lines(3, tmp), lines(4, tmp), 0)
End Sub

Public Function firstItem(pstrItems As String, pstrDelim As String) As String

Dim lngPos As Long
Dim strRes As String
'Dim strDelim As String

strRes = ""

lngPos = InStr(pstrItems, pstrDelim)

If lngPos > 0 Then
  strRes = Left$(pstrItems, lngPos - 1)
  pstrItems = Mid$(pstrItems, lngPos + 1)
Else
  strRes = pstrItems
  pstrItems = ""
End If

firstItem = strRes

End Function
如果您需要任何进一步的细节,请告诉我

背景:这是windows mobile 6.5设备上图片框中的签名。请参阅下面的图像及其相关字符串。希望这能有所帮助

String for SIGNATURE 280172:
3711*371127152715103510351F2C1F2C312231223C1C3C1C3D203D20352D352D333233323D2E3D2E52225222671A671A6C196C196D1A6D1A6D1D6D1D69226922652665266428642864296429652965296E236E23781E781E8718871891179117961896189A199A199B1B9B1B9D1E9D1E9F209F20A021A021A021

添加附件堆栈使其成为png,但它是bmp文件,但它是204 x 64 1位深度的图像

重新排序的字符串(按Spektre)

单个水平线构成以下字符串:

101F*101F
1D21 1D21
2121 2121 
2820 2820     
2C20 2C20
3120 3120
3921 3921
3F21 3F21
4521 4521
4A21 4A21
5122 5122
5822 5822
6121 6121
6421 6421
6721 6721
6A20 6A20
6C20 6C20
6F20 6F20
7220 7220
7520 7520
7720 7720
7920 7920
7D20 7D20
8020 8020
8120 8120
8320 8320
861F 861F
871F 871F
891F 891F
8A1F 8A1F
8D1F 8D1F
8F1F 8F1F
931F 931F
961F 961F
971F 971F
9A1F 9A1F
9C1F 9C1F
9D1E 9D1E
A11E A11E
A31E A31E
A51D A51D
A71D A71D
A91D A91D
AA1C AA1C
AB1C AB1C
AD1C AD1C
AE1C AE1C
B01C B01C
B11B B11B
B21B B21B
B41B B41B
B51A B51A
B61A B61A
B81A B81A
B919 B919
BB19 BB19
BC19 BC19
BD19 BD19
BE19 BE19
BF19 BF19
C019 C019
C11A C11A
C31A C31A
C41A C41A
C51A C51A
C61B C61B
C71B C71B
C81C C81C
C81C 

这就是PictureBox签名成为字符串的原因:

'signature
Public gSigPoints() As Long
Public gSigLines() As Long

Public gSigPointCount As Long
Public gSigLinesCount As Long

Public Function PackBMP() As String

Dim tmpStr1 As String
Dim tmpStr2 As String
Dim tmpStr3 As String
Dim tmpStr4 As String
Dim tmp As Long

    gJob_Signature = ""

    For tmp = 1 To gSigPointCount

        tmpStr1 = CStr(Hex(gSigPoints(1, tmp)))
        tmpStr2 = CStr(Hex(gSigPoints(2, tmp)))

        If Len(tmpStr1) = 2 And Len(tmpStr2) = 2 Then
          gJob_Signature = gJob_Signature & tmpStr1 & tmpStr2 '& ";" & ";"
        Else
          If Len(tmpStr1) = 1 Then tmpStr1 = "0" & tmpStr1
          If Len(tmpStr2) = 1 Then tmpStr2 = "0" & tmpStr2
          If Len(tmpStr1) = 2 And Len(tmpStr2) = 2 Then
            gJob_Signature = gJob_Signature & tmpStr1 & tmpStr2  '& ";"& ";"
          End If
        End If


    Next 'tmp

    gJob_Signature = gJob_Signature & "*"

    For tmp = 1 To gSigLinesCount

        tmpStr1 = CStr(Hex(gSigLines(1, tmp)))
        tmpStr2 = CStr(Hex(gSigLines(2, tmp)))
        tmpStr3 = CStr(Hex(gSigLines(3, tmp)))
        tmpStr4 = CStr(Hex(gSigLines(4, tmp)))

        If Len(tmpStr1) = 2 And Len(tmpStr2) = 2 And Len(tmpStr3) = 2 And Len(tmpStr4) = 2 Then
          gJob_Signature = gJob_Signature & tmpStr1 & tmpStr2 & tmpStr3 & tmpStr4  '& ";"
        Else
          If Len(tmpStr1) = 1 Then tmpStr1 = "0" & tmpStr1
          If Len(tmpStr2) = 1 Then tmpStr2 = "0" & tmpStr2
          If Len(tmpStr3) = 1 Then tmpStr3 = "0" & tmpStr3
          If Len(tmpStr4) = 1 Then tmpStr4 = "0" & tmpStr4

          If Len(tmpStr1) = 2 And Len(tmpStr2) = 2 And Len(tmpStr3) = 2 And Len(tmpStr4) = 2 Then
            gJob_Signature = gJob_Signature & tmpStr1 & tmpStr2 & tmpStr3 & tmpStr4   '& ";"
          End If
        End If

    Next 'tmp

End Function


Public Sub DrawBMP(ByRef pic As PictureBox)
Dim x As Long

  pic.Cls
  For x = 1 To gSigPointCount
    Call pic.DrawPoint(gSigPoints(1, x), gSigPoints(2, x))
  Next x

  For x = 1 To gSigLinesCount
    Call pic.DrawLine(gSigLines(1, x), gSigLines(2, x), gSigLines(3, x), gSigLines(4, x), 0)
  Next x
  pic.Refresh

End Sub


Public Sub AddPoint(x As Long, Y As Long)

  gSigPointCount = gSigPointCount + 1
  ReDim Preserve gSigPoints(2, gSigPointCount)
  gSigPoints(1, gSigPointCount) = x
  gSigPoints(2, gSigPointCount) = Y

End Sub



Public Sub AddLine(x As Long, Y As Long, x1 As Long, y1 As Long)

  gSigLinesCount = gSigLinesCount + 1
  ReDim Preserve gSigLines(4, gSigLinesCount)
  gSigLines(1, gSigLinesCount) = x
  gSigLines(2, gSigLinesCount) = Y
  gSigLines(3, gSigLinesCount) = x1
  gSigLines(4, gSigLinesCount) = y1

End Sub

'********signature
Private miX As Double
Private miY As Double
Private isup As Boolean
'*********end of signature

'@@ singnatures
Private Sub picDraw_MouseDown(Button As Long, Shift As Long, x As Double, Y As Double)

    picDraw.DrawPoint x, Y, 0
    picDraw.Refresh
    Call AddPoint(x, Y)
    miX = x
    miY = Y
    isup = False

End Sub



Private Sub picDraw_MouseMove(Button As Long, Shift As Long, x As Double, Y As Double)

  If isup Then
    miX = x
    miY = Y
    isup = False
  Else

    If Button = 1 Then

      picDraw.DrawLine miX, miY, x, Y, 0
      picDraw.Refresh
      Call AddLine(miX, miY, x, Y)
      miX = x
      miY = Y
    End If

  End If

End Sub



Private Sub picDraw_MouseUp(ByVal Button As Long, ByVal Shift As Long, ByVal x As Double, ByVal Y As Double)
  isup = True
End Sub

这就是我所能看到的关于签名图片框的内容。

< P>我从你所发布的代码中找出编码(尽管必须将它传送到C++),所以编码:

  • 字符串以点列表开头

    每个点以4位十六进制数表示。前两个十六进制数字是点的坐标
    x
    ,后两个数字是点的坐标
    y
    。(可能会标记每个鼠标按下事件,以便保存图像连续绘制次数的信息)

  • 然后是分隔符
    *

  • 在该行列表出现之后

    每行包含2个点,因此每行总共包含8位十六进制数。序列为每个坐标的
    x0、y0、x1、y1
    2位十六进制数。如果字符串仅包含4位十六进制数(结尾),则它将标记签名字符串的结尾

  • 因此,当您想要制作自己的签名代码时,请执行以下操作:

  • 清除点列表和线列表

  • 鼠标按下(左键单击或笔点击)事件

    将当前鼠标/笔位置添加到点列表,并将其作为线列表的起点

  • 鼠标/笔移动事件

    首先确定鼠标按钮是否仍在点击,或者笔是否仍在敲击键盘。如果没有,则忽略此事件。如果是,则将当前鼠标位置添加到行列表中两次(这就是为什么它们在第一个结束当前行和第二个开始新行时被复制的原因)

  • 鼠标/笔启动事件

    关闭实际行,以便将当前鼠标位置添加到行列表中一次

  • 导出前

    复制行列表中的最后一点以标记字符串的结尾

  • 仅此而已。如果需要转换已绘制的图像(光栅),则可能会遇到比较问题,因为不太可能按照作者签名的方式对图像进行矢量化。导致相同图像的不匹配。另外,最后一个三倍的点很可能是因为鼠标/笔向上事件的编码错误,在
    鼠标移动
    鼠标向上
    事件中同时添加相同的点

    以这种方式编码的图像限制为256x256像素

    这里是第一个签名字符串的解码图像示例:

    签名="221A*221A270A250325032007200716171717160D2A0D2A0738073F073F0B3E0B3E1531153121221221212C182C18301630117311731311A311A302230222E2272E2272D2C2C2F2C2F2C2F2C2F312C312C2F2F2C2F2B33126333223322371D381C3B1B3B1B3B1B3C1C3C3C3C3C3D1F3D3D3D3D3D3D3D3A3A3A363A3639393939393939383A3232323A3A3A383A364B175B41185118511D511D5122512250240244F294F294F2C4F2C4C4E2F4E2F4F315030523052305522C552C552C582958295D22601E601E61E61C611C621B621B621A601A601A5D1B5D1B5B1E5B1E57235235328512B512 B502E502F502F52131515152315433054530582E52E592D5C2C55C55C55C55C5F2A64286428652865286528692666641D4642727272518771188718B71988B41879881A881A891B891B881C881C871E871E861F861F85208520842184218222822212481247F257F257E257E257D257C247C247C217C217C217D1F7D1F7E1C7E1C801A801A81198198821782178331783178418851A851A851C851C862086228626258625772787872B872B882E882E89328A338E348E3490390339332972F2972F9A2B717AF716BAB5177B716BAF2972B716BAF2972B717B716BAF717B717B716";

    此处为方形示例

    signature=“0808*080820820202020008200820080808080808”

    因此,重新排序时:

    0808  // point(8h,8h);
    *     // separator
    08 08 20 08 // line( 8h, 8h,20h, 8h)
    20 08 20 20 // line(20h, 8h,20h,20h)
    20 20 08 20 // line(20h,20h, 8h,20h)
    08 20 08 08 // line( 8h,20h, 8h, 8h)
    08 08       // not enough points -> end of string
    
    [Edit1]光栅图像到字符串的转换

    首先,您需要将图像转换为矢量形式。有许多复杂的方法可以将光栅图像多边形化为矢量形式,但它们通常使用数学、图像处理、结构等高级知识。。。需要在这方面有广泛的知识。因为我假设你需要它只是为了在设备上可视化一些东西,所以我会使用非常简单的转换,导致不合理的大结果(与高级方法相比)。如果您的设备没有太小的字符串大小限制,那么您应该很好,否则您需要使用比以下更高级的设备:

  • 清除向量表示法

    点列表和线列表

  • 在图像的所有水平线中循环

  • 处理每一行

  • 从当前位置查找第一组像素
    x0
  • 从当前位置查找第一个未设置的像素
    x1
  • 如果找到
    x0,x1
    ,则

    • 添加点
      (x0,y)
    • 添加行
      (x0,y,x
      
      0808  // point(8h,8h);
      *     // separator
      08 08 20 08 // line( 8h, 8h,20h, 8h)
      20 08 20 20 // line(20h, 8h,20h,20h)
      20 20 08 20 // line(20h,20h, 8h,20h)
      08 20 08 08 // line( 8h,20h, 8h, 8h)
      08 08       // not enough points -> end of string
      
      // load input 2D BW (binary) image
      backbuffer in;
      in.bmp->LoadFromFile("in.bmp");
      in.resize(in.bmp->Width,in.bmp->Height);
      
      int x0,x1,x,y;
      // clear signature vecor represenytation
      gSigPoints.num=0;
      gSigLines.num=0;
      for (y=0;y<in.ys;y++)
       for (x=0;x<in.xs;)
          {
          for (;(x<in.xs)&&(!in.pyx[y][x]);x++); x0=x;    // find start of V-line
          for (;(x<in.xs)&&( in.pyx[y][x]);x++)  x1=x;    // find end of V-line
          if (x0<in.xs)                                   // add pnt,line to signature
              {
              gSigPoints.add(x0);
              gSigPoints.add(y );
              gSigLines.add(x0);
              gSigLines.add(y );
              gSigLines.add(x1);
              gSigLines.add(y );
              }
          }
      // update string and screen
      txt=PackBMP();
      draw();
      
      //---------------------------------------------------------------------------
      #include "list.h"
      //---------------------------------------------------------------------------
      List<DWORD> gSigPoints;
      List<DWORD> gSigLines;
      // some test examples:
      //AnsiString txt="221A*221A270A270A2503250320072007171617160D2A0D2A07380738073F073F0B3E0B3E15311531222122212C182C183016301631173117311A311A302230222E272E272D2C2D2C2C2F2C2F2C312C312C2F2C2F2E2B2E2B3126312633223322371D371D381C381C3B1B3B1B3C1C3C1C3D1F3D1F3D243D243C2D3C2D3A333A333A363A36393939393B383B383D363D36412E412E46264626492049204B1B4B1B4E184E184F174F175017501751185118511D511D51225122502450244F294F294F2C4F2C4E2F4E2F4F314F315030503052305230552C552C582958295D225D22601E601E611C611C621B621B621A621A601A601A5D1B5D1B5B1E5B1E5723572353285328512B512B502E502E502F502F513151315231523154305430582E582E592D592D5C2C5C2C5F2A5F2A6428642865286528692669266D246D247122712275207520791D791D7D1B7D1B81198119841884188618861887198719881A881A891B891B881C881C871E871E861F861F852085208421842182228222812481247F257F257E257E257D257D257C247C247C217C217D1F7D1F7E1C7E1C801A801A81198119821782178317831784188418851A851A851C851C86208620862286228625862587278727872B872B882E882E893289328A338A338E348E349033903393329332972F972F9A2D9A2D9F299F29A426A426AB20AB20AF1CAF1CB517B517B716B716B716";
      //AnsiString txt="3711*371127152715103510351F2C1F2C312231223C1C3C1C3D203D20352D352D333233323D2E3D2E52225222671A671A6C196C196D1A6D1A6D1D6D1D69226922652665266428642864296429652965296E236E23781E781E8718871891179117961896189A199A199B1B9B1B9D1E9D1E9F209F20A021A021A021";
      AnsiString txt="0808*08082008200820202020082008200808";
      //---------------------------------------------------------------------------
      AnsiString Hex(DWORD x,DWORD digits)
          {
          int i;
          char *tab="0123456789ABCDEF";
          AnsiString s="";
          if (digits>8) digits=8;
          s.SetLength(digits);
          for (i=digits;i>0;i--,x>>=4) s[i]=tab[x&15];
          return s;
          }
      //---------------------------------------------------------------------------
      AnsiString PackBMP()
          {
          DWORD i;
          AnsiString sig="";
          // all points
          for (i=0;i+1<gSigPoints.num;)
              {
              sig+=Hex(gSigPoints[i],2); i++; // x
              sig+=Hex(gSigPoints[i],2); i++; // y
              }
          // separator
          sig+="*";
          // all lines
          for (i=0;i+3<gSigLines.num;i++)
              {
              sig+=Hex(gSigLines[i],2); i++;  // x0
              sig+=Hex(gSigLines[i],2); i++;  // y0
              sig+=Hex(gSigLines[i],2); i++;  // x1
              sig+=Hex(gSigLines[i],2); i++;  // y1
              }
          return sig;
          }
      //---------------------------------------------------------------------------
      void UnpackBMP(AnsiString &sig)
          {
          DWORD a,x,y;
          int i=1,l=sig.Length();
          // all points
          for(gSigPoints.num=0;(i+3<=l)&&(sig[i]!='*');)
              {
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10;        x =a; i++;
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10; x<<=4; x|=a; i++;
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10;        y =a; i++;
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10; y<<=4; y|=a; i++;
              gSigPoints.add(x);
              gSigPoints.add(y);
              }
          // separator
          i++;
          // all lines
          for(gSigLines.num=0;i+7<=l;)
              {
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10;        x =a; i++;
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10; x<<=4; x|=a; i++;
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10;        y =a; i++;
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10; y<<=4; y|=a; i++;
              gSigLines.add(x);
              gSigLines.add(y);
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10;        x =a; i++;
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10; x<<=4; x|=a; i++;
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10;        y =a; i++;
              a=sig[i]-'0'; if (a>9) a+='0'-'A'+10; y<<=4; y|=a; i++;
              gSigLines.add(x);
              gSigLines.add(y);
              }
          }
      //---------------------------------------------------------------------------
      void DrawBMP(TCanvas *can)
          {
          DWORD i,x,y;
          // all points
          for (i=0;i+1<gSigPoints.num;)
              {
              x=gSigPoints[i]; i++;
              y=gSigPoints[i]; i++;
              can->Pixels[x][y]=can->Pen->Color;
              }
          // all lines
          for (i=0;i+3<gSigLines.num;)
              {
              x=gSigLines[i]; i++;
              y=gSigLines[i]; i++;
              can->MoveTo(x,y);
              x=gSigLines[i]; i++;
              y=gSigLines[i]; i++;
              can->LineTo(x,y);
              }
          }
      //---------------------------------------------------------------------------
      void signature_on_mouse(backbuffer &scr)
          {
          DWORD x,y;
          // mouse left button last and actual
          bool q0=scr.sh0.Contains(ssLeft);
          bool q1=scr.sh1.Contains(ssLeft);
          bool _redraw=false;
          // actual mouse position
          x=scr.mx1;
          y=scr.my1;
          // on mouse down event
          if ((!q0)&&(q1))
              {
              gSigPoints.add(x); gSigLines.add(x);
              gSigPoints.add(y); gSigLines.add(y);
              _redraw=true;
              }
          // on mouse move event
          if ((q0)&&(q1))
              {
              gSigLines.add(x);
              gSigLines.add(y);
              gSigLines.add(x);
              gSigLines.add(y);
              _redraw=true;
              }
          // mouse mouse up event
          if ((q0)&&(!q1))
              {
              gSigLines.add(x);
              gSigLines.add(y);
              _redraw=true;
              txt=PackBMP();
              }
          // right mouse button clears signature
          if (scr.sh1.Contains(ssRight))
              {
              gSigPoints.num=0;
              gSigLines.num=0;
              _redraw=true;
              }
          if ((_redraw)&&(scr.win)) scr.win->Repaint();
          scr.rfs_mouse();
          }
      //---------------------------------------------------------------------------