Signature BLOB

jflaplante

Member
Licensed User
Longtime User
Hi,

By combining the signature capture tutorial:

http://www.b4x.com/forum/basic4android-getting-started-tutorials/9096-signature-capture-tutorial.html

and the SQL tutorial:

http://www.b4x.com/forum/basic4android-getting-started-tutorials/6736-sql-tutorial.html#post39108

I was able to capture a signature, save it to a png file, read it back, convert it into a blob in an sqlite database with success. This is used in a screen that displays an invoice header and capture the signature at the bottom.

My relevant code looks like this:

B4X:
SignatureCapture.Save(SD, File.DirRootExternal, "sign.png")
ToastMessageShow("Signature saved to: " & File.Combine(File.DirRootExternal, "sign.png"), True)
   
Dim InputStream1 As InputStream
InputStream1 = File.OpenInput(File.DirRootExternal, "sign.png")
Dim OutputStream1 As OutputStream
OutputStream1.InitializeToBytesArray(1000)
File.Copy2(InputStream1, OutputStream1)
Dim Buffer() As Byte
Buffer = OutputStream1.ToBytesArray
   
'write the image to the database
Main.SQL.ExecNonQuery2("UPDATE tab_inv SET signature = ? where inv ="&Main.selected_invoice, Array As Object(Buffer))


This led me to two questions:

1- Using the signature capture module general configuration, is there a shorter way to do this by eliminating the png file altogether and converting the SD data directly into the bytes array necessary for the SQLite blob update?

2- How would one go about pre-populating the signature capture canvas with a blob freshly read from an sqlite database. A previously saved signature in fact?

Thanks in advance for any help.

JF.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. You can change the Save method to return an array of bytes:
B4X:
Sub Save(SD As SignatureData, Dir As String, Name As String) As Byte()
   Dim out As OutputStream
   out.InitializeToBytesArray(100)
   SD.Canvas.Bitmap.WriteToStream(out, 100, "PNG")
   Return out
End Sub

2. First convert the Blob to an image and then use Canvas.DrawBitmap to draw it.
 
Upvote 0

jflaplante

Member
Licensed User
Longtime User
Thanks Erel,

Both points worked beautifully! I will have to learn more about the "android.graphics.Rect" part because that where my previous tests were problematic.

Thanks again and have a nice Superbowl!

JF.
 
Upvote 0

Eric H

Active Member
Licensed User
Longtime User

I am trying to use this code in a project I am working on and I have 2 issues:

1. Since I am not actually saving the signature as an actual PNG file on my device (I am trying to use the signature stream to store it as a PNG-BLOB in my SQLite database), I am not sure why I would still have "Dir As String" and maybe even "Name As String" as arguments for the new Save() method.

2. The more serious issue I have when using this method as written in my quoted text is an error:
B4X:
Error: B4A line: 36
Return out

javac 1.7.0_25
src\b4a\example\signaturecapture.java:85: error: inconvertible types

if (true) return (byte[])(_out.getObject());
                         ^
  required: byte[]
  found:    OutputStream
1 error

Here is the actual code from signaturecapture.java for that section:
B4X:
75  public static byte[]  _v0(anywheresoftware.b4a.BA _ba,b4a.example.signaturecapture._signaturedata _sd,String _dir,String _name) throws Exception{
76  anywheresoftware.b4a.objects.streams.File.OutputStreamWrapper _out = null;
77' //BA.debugLineNum = 32;BA.debugLine="Sub Save(SD As SignatureData, Dir As String, Name As String) As Byte()";
78' //BA.debugLineNum = 33;BA.debugLine="Dim out As OutputStream";
79  _out = new anywheresoftware.b4a.objects.streams.File.OutputStreamWrapper();
80' //BA.debugLineNum = 34;BA.debugLine="out.InitializeToBytesArray(100)";
81  _out.InitializeToBytesArray((int)(100));
82' //BA.debugLineNum = 35;BA.debugLine="SD.Canvas.Bitmap.WriteToStream(out, 100, \"PNG\")";
83  _sd.Canvas.getBitmap().WriteToStream((java.io.OutputStream)(_out.getObject()),(int)(100),BA.getEnumFromString(android.graphics.Bitmap.CompressFormat.class,"PNG"));
84' //BA.debugLineNum = 36;BA.debugLine="Return out";
85  if (true) return (byte[])(_out.getObject());
86' //BA.debugLineNum = 37;BA.debugLine="End Sub";
87  return null;
88  }

Thanks,
Eric H
 
Last edited:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…