Vb.net 将签名位图转换为签名字符串(非常奇怪)
基本上,我需要将位图图像转换为字符串,但它不是一个常见的字符串 困境在于该字符串由两部分组成: 1) 要点 2) 线条 我需要将图像转换为由*分隔的两部分 我得到的一个例子是:Vb.net 将签名位图转换为签名字符串(非常奇怪),vb.net,image,graphics,bitmap,Vb.net,Image,Graphics,Bitmap,基本上,我需要将位图图像转换为字符串,但它不是一个常见的字符串 困境在于该字符串由两部分组成: 1) 要点 2) 线条 我需要将图像转换为由*分隔的两部分 我得到的一个例子是: "221A*221A270A270A2503250320072007171617160D2A0D2A07380738073F073F0B3E0B3E15311531222122212C182C183016301631173117311A311A302230222E272E272D2C2D2C2C2F2C2F2C312C3
"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++),所以编码:
x
,后两个数字是点的坐标y
。(可能会标记每个鼠标按下事件,以便保存图像连续绘制次数的信息)*
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();
}
//---------------------------------------------------------------------------