Converting OpenNetCF GetSignatureEx to Bitmap on Desktop - vb.net

I have a SQLite database which is running on a handheld which is capturing signatures using OpenNetCF's Smart Device Framework 2.1 running under Windows Mobile 6.1. The signatures are captured from the Signature control using the GetSignatureEx method and stored in the database.
What I want to do now is reconstitute the signatures on the desktop, but the desktop does not have a similar control. I looked at the data and it looks like a bunch of vectors, which explains why the data is so compact.
Does anyone have any idea how I can convert the data into a bitmap on the desktop using VB.NET. Thanks.

Found what I wanted on an OpenNetCF forum. The code was originally in C#, but didn't take too long to convert it to VB.NET. This code has been tested on version 2.0 and 2.1 of the OpenNetCF framework, but it will apparently work with version 1.4. Colin
Public Function GetSignature(ByVal arrsig As Byte(), ByVal backcolor As System.Drawing.Color)
Dim pic As System.Windows.Forms.PictureBox
Dim word As Integer
Dim lngIndex As Integer
Dim lngPointsToRead As Integer = 0
Dim lngCurrX As Integer = -1
Dim lngCurrY As Integer = -1
Dim lngPrevX As Integer = -1
Dim lngPrevY As Integer = -1
Dim lngWidth As Integer = 1
Dim lngHeight As Integer
Dim bit As New System.Drawing.Bitmap(1, 1)
Dim g As Graphics = Graphics.FromImage(bit)
pic = New picturebox()
Dim blackpen As New Pen(Color.Black)
If arrsig.Length < 3 Then
Return Nothing
End If
word = arrsig(0)
word = word + System.Convert.ToInt32(arrsig(1)) * 256
lngWidth = word
word = arrsig(2)
word = word + System.Convert.ToInt32(arrsig(3)) * 256
lngHeight = word
bit = New Bitmap(lngWidth, lngHeight)
g = Graphics.FromImage(bit)
g.Clear(backcolor)
lngIndex = 4
While (True)
If (lngIndex >= arrsig.Length) Then
Exit While
End If
If (lngPointsToRead = 0) Then
word = arrsig(lngIndex)
lngIndex = lngIndex + 1
word = word + System.Convert.ToInt32(arrsig(lngIndex)) * 256
lngPointsToRead = word
lngPrevX = -1
lngPrevY = -1
Else
If (lngCurrX = -1) Then
word = arrsig(lngIndex)
If (lngWidth > 255) Then
lngIndex = lngIndex + 1
word = word + System.Convert.ToInt32(arrsig(lngIndex)) * 256
End If
lngCurrX = word
ElseIf (lngCurrY = -1) Then
word = arrsig(lngIndex)
If (lngHeight > 255) Then
lngIndex = lngIndex + 1
word = word + System.Convert.ToInt32(arrsig(lngIndex)) * 256
End If
lngCurrY = word
lngPointsToRead = lngPointsToRead - 1
If (lngPrevX <> -1) Then
g.DrawLine(blackpen, lngPrevX, lngPrevY, lngCurrX, lngCurrY)
End If
lngPrevX = lngCurrX
lngPrevY = lngCurrY
lngCurrX = -1
lngCurrY = -1
End If
End If
lngIndex = lngIndex + 1
End While
pic.Image = bit
Return pic.Image
End Function

Related

Create an image out of Quick Shift result

I've implemented the quickshift Quick Shift image segmentation algorithm in vb.net.
Now I'm looking for a C++ or vb.net source code which converts the results of the Quick Shift back into an image.
I tried the following code but the result is not satisfactory.
In the meantime I've implemented it in vb.net myself
but the result is not satisfactory.
Dim qs_obj As VlQS
Dim img_dbl() As Double
Dim result_image As Bitmap
img_dbl = ConvertRGB2LabDouble(Source_Image_PCA)
qs_obj = vl_quickshift_new(img_dbl, Source_Image_PCA.Height, Source_Image_PCA.Width, 3)
vl_quickshift_process(qs_obj)
vl_quickshift_set_kernel_size(qs_obj, 10)
vl_quickshift_set_max_dist(qs_obj, 10)
result_image = CType(Source_Image_PCA.Clone, Bitmap)
For y As Integer = 0 To Source_Image_PCA.Height - 1
For x As Integer = 0 To Source_Image_PCA.Width - 1
Dim pixelindex As Integer = qs_obj.parents(y * Source_Image_PCA.Width + x)
Dim col As Integer = pixelindex Mod (Source_Image_PCA.Width)
Dim row As Integer = pixelindex \ Source_Image_PCA.Width
Dim pixel_val As Color
pixel_val = Source_Image_PCA.GetPixel(col, row)
result_image.SetPixel(x, y, pixel_val)
Next
Next
picImageSpecialFnc.Image = result_image

vb.net efficiently finding byte sequence in byte array

so I am creating a piece of software that in short, has a list of original byte sequences and new sequences that those bytes need to be changed into, kinda like this in text form "original location(currently irrelevant as sequence can be in different places) $ 56,69,71,73,75,77 : 56,69,71,80,50,54"
I already have code that works fine, however there can be up to 600+ of these sequences to find and change and in some cases it is taking a really really long time 15 mins +, i think it is down to how long it is taking to find the sequences to them change so i am trying to find a better way to do this as currently it is unusable due to how long it takes.
I have copied the whole code for this function below in hopes one of you kind souls can have a look and help =)
Dim originalbytes() As Byte
Dim fd As OpenFileDialog = New OpenFileDialog()
fd.Title = "Select the file"
fd.Filter = "All files (*.*)|*.*|All files (*.*)|*.*"
fd.FilterIndex = 2
If fd.ShowDialog() = DialogResult.OK Then
TextBox2.Text = fd.FileName
originalbytes = File.ReadAllBytes(fd.FileName)
End If
Dim x As Integer = 0
Dim y As Integer = 0
Dim textbox1array() = TextBox1.Lines
Dim changedbytes() = originalbytes
Dim startvalue As Integer = 0
Dim databoxarray() As String
Dim databoxarray2() As String
While x < textbox1array.Length - 1
'for each change to make
databoxarray = textbox1array(x).Replace(" $ ", vbCr).Replace(" : ", vbCr).Split
databoxarray2 = databoxarray(1).Replace(",", vbCr).Split
Dim databox2bytes() As String = databoxarray2
'copy original bytes line to databox2 lines
y = 0
While y < (originalbytes.Length - databox2bytes.Length)
'repeat for all bytes in ori file - size of data to find
If originalbytes(y) = databox2bytes(0) Then
startvalue = y
Dim z As String = 1
Dim samebytecounter As Integer = 1
While z < databox2bytes.Length
'repeat for all ori bytes
If originalbytes(y + z) = databox2bytes(z) Then
samebytecounter = samebytecounter + 1
End If
z = z + 1
End While
If samebytecounter = databox2bytes.Length Then
'same original data found, make changes
Dim bytestoinsert() As String = databoxarray(2).Replace(",", vbCr).Split
Dim t As Integer = 0
While t < bytestoinsert.Length
changedbytes(startvalue + t) = bytestoinsert(t)
t = t + 1
End While
End If
End If
y = y + 1
End While
x = x + 1
End While
File.WriteAllBytes(TextBox2.Text & " modified", changedbytes)
Let 's take a look at that inner while loop in your code, there are some things that can be optimized:
There is no need to check the total length all the time
Dim length as Integer = originalbytes.Length - databox2bytes.Length
While y < length
'repeat for all bytes in ori file - size of data to find
If originalbytes(y) = databox2bytes(0) Then
startvalue = y
z is not necessary, samebytecounter does exactly the same
Dim samebytecounter As Integer = 1
This while loop is a real bottleneck, since you always check the full length of your databox2bytes, you should rather quit the while loop when they don't match
While samebytecounter < databox2bytes.Length AndAlso originalbytes(y + samebytecounter ) = databox2bytes(samebytecounter )
samebytecounter = samebytecounter + 1
End While
This seems fine, but you already splitted the data at the top of your while loop, so, no need to create another array that does the same operation again
If samebytecounter = databox2bytes.Length Then
'same original data found, make changes
Dim t As Integer = 0
While t < databoxarray2.Length
changedbytes(startvalue + t) = databoxarray2(t)
t = t + 1
End While
End If
End If
y = y + 1
End While
For the rest I would agree that the algorithm you created is hugely inefficient, theoretically your code could have been rewritten like eg: (didn't really test this code)
Dim text = System.Text.Encoding.UTF8.GetString(originalbytes, 0, originalbytes.Length)
dim findText = System.Text.Encoding.UTF8.GetString(stringToFind, 0, stringToFind.Length)
dim replaceWith = System.Text.Encoding.UTF8.GetString(stringToSet, 0, stringToSet.Length)
text = text.Replace( findText, replaceWith )
dim outbytes = System.Text.Encoding.UTF8.GetBytes(text)
which would probably be a huge time saver.
For the rest your code seems to be created in such a way that nobody will really understand it if it's laying around for a month or so, I would say, including yourself

Finding a certain character in Visio and reformating the following text

Due to a tight timing for one of my projects with Visio I need to look over all the shapes in All the pages for certain character (name it "&") and then change the color of n character after it, so i wrote a code like follow but it does not go through all occurrences in one text block, after it hits the first one the loop exits... I just need help to resolve it my mind is kind of frozen now... sorry if my question is silly
Sub test()
Dim PageObj As Visio.Page
Dim shpsObj As Visio.Shapes
Dim shpObj As Visio.Shape
Dim oShpChar As Visio.Characters
Set PageObj = ActivePage
Set shpsObj = PageObj.Shapes
For Each shpObj In shpsObj
'Dim iLength As Integer
Dim iBeginOffset As Integer, iEndOffset As Integer
Set oShpChar = shpObj.Characters
Do
iBeginOffset = InStr(oShpChar.Text, "&test")
'If iBeginOffset = 0 Then Exit Do ' # Not found -> end the loop
iEndOffset = iBeginOffset + 3
oShpChar.Begin = iBeginOffset
oShpChar.End = iEndOffset
oShpChar.CharProps(visCharacterColor) = 9
oShpChar.Begin = oShpChar.Begin + 1
oShpChar.End = oShpChar.CharCount
Loop While (iEndOffset < oShpChar.CharCount)
Next
End Sub
I just tagged it for Excel too since the overall concept is the same...
The problem is found...
Unfortunately Microsoft Visio does not hold the updated value for "Character.Begin" and "Character.End" properties through outer loop, in other word it maintained but not accessible by other method such as"CharProps". so I introduced a counter outside of while loop to keep track of each new value for the mentioned property, hope it helps others to resolve their issue too, it's cost me 7 hours
(I am not a developer so please correct me if I made a mistake in my explanations)!
Sub test()
Set PageObj = ActivePage
Set shpsObj = PageObj.Shapes
For Each shpObj In shpsObj
Dim searchWord As String
Dim placeHolder As Integer
Dim iLength As Integer
Dim iBeginOffset As Integer, iEndOffset As Integer
Set oShpChar = shpObj.Characters
searchWord = "&test"
iLength = oShpChar.CharCount
Do
iBeginOffset = InStr(oShpChar.Text, searchWord)
If iBeginOffset = 0 Then Exit Do ' searchWord Not found -> end the loop
iBeginOffset = iBeginOffset + placeHolder
placeHolder = iBeginOffset + Len(searchWord) - 1
iEndOffset = iBeginOffset + Len(searchWord) - 1
oShpChar.Begin = iBeginOffset
oShpChar.End = iEndOffset
If iEndOffset > iLength Then Exit Do ' Preventing the last run
oShpChar.CharProps(visCharacterColor) = 9
oShpChar.Begin = oShpChar.Begin + Len(searchWord) - 1
oShpChar.End = iLength
Loop While (iEndOffset < iLength)
Next
End Sub

Print multiple images in vb.net

In VB.NET, I need to print multiple Images of bar codes by arranging them in tabular format. For now what I am doing is, Creating the bar codes and adding them in new picture box. These Picture boxes are added on a panel which I am creating on form at run time and print that panel (with picture boxes in 4x9 table).
But, when I need to print more that 36 bar codes, this idea doesn't work.
So, Please suggest me some improvements in my code or any other way to do this job.
I am sorry, here is the code for generating images and adding them to the panel..
''' Method for create bar code images with a loop and adding them to the panel by picture box...
Private Function GetBarcodeText(RowId As Guid)
Dim BarcodeValue As StringBuilder = New StringBuilder(96)
Dim temp As New StringBuilder
Dim data As String
Dim param = New SqlParameter()
Dim imageNo As Integer = 0
Dim colorValue As String = ""
Dim scaleValue As String = ""
'' Adding the panel on the form which is dynamically created
Me.Controls.Add(outputPanel)
'' Setting the Initial size for the panel
outputPanel.Size = New Point(794, 112)
outputPanel.Name = "outputPanel"
outputPanel.BackColor = Drawing.Color.White
param.ParameterName = "#RowId"
param.Value = RowId
param.SqlDbType = SqlDbType.UniqueIdentifier
' Get the particular row of data from database
dt = objStockProvider.GetBarcodeDetails(param)
' GET colour code
Dim color As String = dt.Rows(0)("COLOUR").ToString()
Dim countColors As Integer = 0
' Get the color code numbers
param.ParameterName = "#Dscale"
param.Value = dgvViewTickets.CurrentRow.Cells("SCALE").Value.ToString()
countColors = objStockProvider.CountColorCodes(param)
For i = 1 To countColors
For j As Integer = 1 + ((12 / countColors) * (i - 1)) To (12 / countColors) * i
If dt.Rows(0)("S" + j.ToString()) <> 0 Then
Dim totalTicketsForASize As Integer
totalTicketsForASize = dt.Rows(0)("S" + j.ToString())
For k As Integer = 1 To totalTicketsForASize
' Set Bar code value which has to create
BarcodeValue = "123456789012"
' Create Barcode Image for given value
Dim image = GetBarcodeImage(BarcodeValue, colorValue, scaleValue)
If image IsNot Nothing Then
'' Create picture box to contain generated Image.
Dim pcbImage As New PictureBox
pcbImage.Width = W
pcbImage.Height = H
pcbImage.Image = image
pcbImage.Location = New Point(X, Y)
imageNo += 1
If imageNo Mod 4 = 0 Then
X = 15
Y += H
outputPanel.Height += H
Else
X += W
Y = Y
End If
pcbImage.Visible = True
'' Adding picture box to panel
outputPanel.Controls.Add(pcbImage)
End If
Next
End If
Next
color = color.Substring(color.IndexOf(",") + 1, color.Length - color.IndexOf(",") - 1)
Next
PrintGeneratedTickets()
End Function
Now, I am printing the panel by following method:
Private Sub PrintGeneratedTickets()
bmp = New Bitmap(outputPanel.DisplayRectangle.Width, outputPanel.DisplayRectangle.Height)
Dim G As Graphics = Graphics.FromImage(bmp)
G.DrawRectangle(Pens.White, New Rectangle(0, 0, Me.outputPanel.DisplayRectangle.Width, Me.outputPanel.DisplayRectangle.Height))
Dim Hdc As IntPtr = G.GetHdc()
SendMessage(outputPanel.Handle, WM_PRINT, Hdc, DrawingOptions.PRF_OWNED Or DrawingOptions.PRF_CHILDREN Or DrawingOptions.PRF_CLIENT Or DrawingOptions.PRF_NONCLIENT)
G.ReleaseHdc(Hdc)
pndocument.DocumentName = bmp.ToString()
Dim previewmode As New PrintPreviewDialog
previewmode.Document = pndocument
previewmode.WindowState = FormWindowState.Maximized
previewmode.PrintPreviewControl.Zoom = 1
pndocument.DefaultPageSettings.Margins.Top = 10
pndocument.DefaultPageSettings.Margins.Bottom = 30
pndocument.DefaultPageSettings.Margins.Left = 16
pndocument.DefaultPageSettings.Margins.Right = 16
pndocument.DefaultPageSettings.Landscape = False
' Set other properties.
previewmode.PrintPreviewControl.Columns = 4
previewmode.PrintPreviewControl.Rows = 9
previewmode.ShowDialog()
Dim file As String = DateTime.Now.ToString()
file = Path.GetFullPath("D:\Bar Codes\" + file.Replace("/", "-").Replace(":", ".") + ".bmp")
bmp.Save(file)
G.Dispose()
outputPanel.Controls.Clear()
End Sub
This code is working fine but what I need to do, is to fix the number of images (4x9) per page. But when I am trying to create more than it, that all are printing on a single page with compressed size.
Also when trying to re-run the code, It shows nothing in preview..
Some body please suggest the correction in code so that I can reprint the tickets and use paging for more than 36 images.
Well, Printing the Images on a panel was not a good idea.. I replaced the panel and created an array of images and used the print document directly and print after arranging images on it.
Thanks.

Trying to create text boxes dynammically and remove them

I am using VB.NET vb 2008 . I am trying to create text boxes dynammically and remove them here is the code i have written so far
Private Sub setTextBox()
Dim num As Integer
Dim pos As Integer
num = Len(word)
temp = String.Copy(word)
Dim intcount As Integer
remove()
GuessBox.Visible = True
letters.Visible = True
pos = 0
'To create the dynamic text box and add the controls
For intcount = 0 To num - 1
Txtdynamic = New TextBox
Txtdynamic.Width = 20
Txtdynamic.Visible = True
Txtdynamic.MaxLength = 1
Txtdynamic.Location = New Point(pos + 5, 0)
pos = pos + 30
'set the font size
Txtdynamic.Font = New System.Drawing.Font("Verdana", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Txtdynamic.Name = "txtdynamic_" & intcount & "_mycntrl"
Txtdynamic.Enabled = False
Txtdynamic.Text = ""
Panel1.Controls.Add(Txtdynamic)
Next
Panel1.Visible = True
Controls.Add(Panel1)
Controls.Add(GuessBox)
Controls.Add(letters)
letter = ""
letters.Text = ""
hang_lable.Text = ""
tries = 0
End Sub`enter code here`
Function remove()
For Each ctrl In Panel1.Controls
Panel1.Controls.Remove(ctrl)
Next
End Function
I am able to create the textboxes but only a few of them are removed. by using For Each ctrl In Panel1.Controls it doesn't retrieve all the controls and some ae duplicated as well.
Change your remove to
Sub remove()
For i As Integer = Panel1.Controls.Count - 1 To 0 Step -1
Panel1.Controls.Remove(Panel1.Controls(i))
Next i
End Sub
If I am not mistaken you should not change a collection in a loop that you are currently looping, using a for each. The safest ways would be to use the index, in reverse, so that the position is not affected.