Using C# to convert base30 image from jsignature - c#

I need some help about .net method to convert jsignature exported data.
I have an Android app sending base30 compressed data (for example "quaok1C2S3Q3W3A2A2I1Uk1y800Z6c1y1y1W2G2w2C2u1O1M1wie800Y2ccm1A1C1Q1S1U2G2y2M1O1u1y4424681y1C1Q2M2Q2w2A2woce_dC200Z2688408ccoeiamiga800000Y48gic1u1ucmaes866402000Z224420000000000002")
and a .Net web service (rest) receving data in order to save them to database and do some business.
At the moment I'm experimenting some problem in converting data from base30 to image.
As example, I'm referring to the SignatureDataConversion_dotNet code in the "extras" folder of the jsignature zip (https://github.com/willowsystems/jSignature) in order to do the conversion and manage data.
But something is not working for me...or, maybe, I've not completely understood how to manage base30 signature in .Net
This is a piece of the code I'm using:
Base30Converter conv = new Base30Converter();
int[][][] bytearray = conv.GetData(base30_string_from_app);
string actual = jSignature.Tools.SVGConverter.ToSVG(bytearray);
var byteArray = Encoding.ASCII.GetBytes(actual);
using (var stream = new MemoryStream(byteArray))
{
var svgDocument = SvgDocument.Open(stream);
var bitmap = svgDocument.Draw();
bitmap.Save("D:\prova.png", ImageFormat.Png);
}
But the image I get seems to be a "partion" of the whole signature sent, with only some strokes.
I've also checked the string I am manipulating: it is the same of what the app is sending.
As confirmation of this I succed in importing it on a html canvas, using jSignature "setData" method.
Thanks in advance for any help
As another example of the probable issue with the base30 conversion to svg in .Net, here we have the svg conversion of a signature exportet from http://willowsystems.github.io/jSignature/#/demo/
[svg]
[https://] dl.dropboxusercontent.com/u/77767500/SVG_from_jsignature_site.svg
this is the base 30 conversion of the same sign:
7yf1Ul1H4232121Z4577dabdllhhne1uf6423Y2587ddn1v1x1G1A1D1wpordd8431Z1338ffppkm1v1Db964210Y158b46ffgqkhqfef8673523_3EZ2519332455410Y315329745ba9me5343421200100000Z22345233345323311000Y142853746743121000Z10041112224332_jVZ746ba553200Y12368cabceb8a74200Z234a4ebcebfdbc65Y68afjdjd9f864334_4SZ110000Y3368745322000000Z1123355584323113000000Y31Z101101201001221
Trying to convert it using
Base30Converter conv = new Base30Converter();
int[][][] bytearray = conv.GetData(stream_to_convert);
string actual = jSignature.Tools.SVGConverter.ToSVG(bytearray);
i get:
[https://] dl.dropboxusercontent.com/u/77767500/SVG_from_jsignature_lib.svg
As you can see the two "svg" conversion seems to be different.
So, maybe, there is something not working properly in the jSignature.Tools for .Net ...

It took me a lot of trial and error with the .NET tools included in the jSignature package, but here's how I eventually got it to generate a PNG from a base30 jSignature string. I'm using VB .NET and returning a System.Drawing.Image (which you can output however you want):
Public Function GetSignaturePNG() As System.Drawing.Image
'jSignature conversion from base30 to SVG
Dim base30Converter As New jSignature.Tools.Base30Converter()
Dim arrBase30Data As Integer()()() = base30Converter.GetData(Me.SigBase30) 'our original base30 string
Dim strSVG As String = jSignature.Tools.SVGConverter.ToSVG(arrBase30Data)
'first convert it to SVG
Dim mySVG As SvgDocument
Dim newStream As New System.IO.MemoryStream(System.Text.ASCIIEncoding.[Default].GetBytes(strSVG))
mySVG = SvgDocument.Open(newStream, Nothing)
'then convert it to PNG
Dim tempStream As New System.IO.MemoryStream()
mySVG.Draw().Save(tempStream, System.Drawing.Imaging.ImageFormat.Png)
Dim img As System.Drawing.Image = System.Drawing.Image.FromStream(tempStream)
Return img
End Function
Update 6.20.2014: Leo, I was able to successfully export your base30 signature string (listed in your original question) as both SVG and PNG. And I got the entire "leo" signature, not just the few broken strokes. So I'm not sure what we're doing differently. Are you sure you're passing in the entire base30 string to the function?

The SVGConverter class uses string.Format to output decimals to the string. If your current culture is e.g. set to German, it will output fractions with a comma instead of points. So, add CultureInfo.InvariantCulture as the first argument to each String.Format in that class to make sure the SVG output is formatted with decimal points.

Related

Convert Base64 String to an Image File and Save it to File System?

I am trying to make a .Net 6 console application that would take in a base64string and then save it to the file system as an actual image file
Example
I have this image
https://cdn.pixabay.com/photo/2016/03/28/12/35/cat-1285634_960_720.png
I would have this image already as a base64 string.
Now I want to save to my file system as "cat-1285634_960_720.png"
I just can't figure out how to do it. All the examples I see say to use Image.Save() but I can't find that in .Net6 and looks like it is removed.
First convert the base64 string to a byte array and then use File.WriteAllBytes(...) to save it:
byte[] imageByteArray = Convert.FromBase64String(base64String);
File.WriteAllBytes("image.png", imageByteArray);

Reading GDAL Data from Tiff images Encoded as a Base64String

I am currently trying to decode a (Geo)Tiff Image encoded as a Base64String back to the original format using C# so that I can access the GDAL Metadata as for example the Dataset.
Problem 1: I can't find any exact explanation on how to convert a Base64String encoded image to a tiff image. The method I found only returns null for tiff.
Tiff tiff;
String base64String = imageDataString.Replace("data:image/png;base64,", ""); // data:image/png;base64,
byte[] byteBuffer = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(byteBuffer);
tiff = Tiff.ClientOpen("in-memory", "r", ms, new TiffStream());
using BitMiracle.LibTiff.Classic.
Problem 2:
If the tiff image was decoded, how do I save it to the harddrive? This step seems to be necessary so that I can open the image to extract the GDAL Dataset as following:
Dataset GdalRoomSet = Gdal.Open(imagePath, 0);
double[] TransformationCoefficients = new double[6];
GdalRoomSet.GetGeoTransform(TransformationCoefficients);
Problem solved itselfe through jps' comment. The question is now obsolete, as I need a completely different approach.

Convert base64 string to jpg/file

I am struggling to find a way to convert a base 64 string to a jpeg or a file without using the Image class. Is it possible to create the file and not save it locally and upload to Azure blob storage?
var bytes = Convert.FromBase64String(base64String);
To keep it completely clean and simple, use something like this:
using (var img = new MemoryStream(bytes))
{
cloudBlockBlob.UploadFromStream(img);
}
This creates a MemoryStream that you can use to call CloudBlockBlob.UploadFromStream().
Edit
Or, like #mike-z said in the comment below, you can use CloudBlockBlob.UploadFromByteArray() directly.

System.Text.Encoding.Default.GetBytes fails

Here is my sample code:
CodeSnippet 1: This code executes in my file repository server and returns the file as encoded string using the WCF Service:
byte[] fileBytes = new byte[0];
using (FileStream stream = System.IO.File.OpenRead(#"D:\PDFFiles\Sample1.pdf"))
{
fileBytes = new byte[stream.Length];
stream.Read(fileBytes, 0, fileBytes.Length);
stream.Close();
}
string retVal = System.Text.Encoding.Default.GetString(fileBytes); // fileBytes size is 209050
Code Snippet 2:
Client box, which demanded the PDF file, receives the encoded string and converts to PDF and save to local.
byte[] encodedBytes = System.Text.Encoding.Default.GetBytes(retVal); /// GETTING corrupted here
string pdfPath = #"C:\DemoPDF\Sample2.pdf";
using (FileStream fileStream = new FileStream(pdfPath, FileMode.Create)) //encodedBytes is 327279
{
fileStream.Write(encodedBytes, 0, encodedBytes.Length);
fileStream.Close();
}
Above code working absolutely fine Framework 4.5 , 4.6.1
When I use the same code in Asp.Net Core 2.0, it fails to convert to Byte Array properly. I am not getting any runtime error but, the final PDF is not able to open after it is created. Throws error as pdf file is corrupted.
I tried with Encoding.Unicode and Encoding.UTF-8 also. But getting same error for final PDF.
Also, I have noticed that when I use Encoding.Unicode, atleast the Original Byte Array and Result byte array size are same. But other encoding types are mismatching with bytes size also.
So, the question is, System.Text.Encoding.Default.GetBytes broken in .NET Core 2.0 ?
I have edited my question for better understanding.
Sample1.pdf exists on a different server and communicate using WCF to transmit the data to Client which stores the file encoded stream and converts as Sample2.pdf
Hopefully my question makes some sense now.
1: the number of times you should ever use Encoding.Default is essentially zero; there may be a hypothetical case, but if there is one: it is elusive
2: PDF files are not text, so trying to use an Encoding on them is just... wrong; you aren't "GETTING corrupted here" - it just isn't text.
You may wish to see Extracting text from PDFs in C# or Reading text from PDF in .NET
If you simply wish to copy the content without parsing it: File.Copy or Stream.CopyTo are good options.

Base64 decoding of a image gives a red question mark

I am encoding and decoding facebook thumbnail image data using base64 strings in unity3d. When the user does not have a profile picture, the resulting image is a red question mark. Is there any way to recognise that an invalid picture is being sent so that I can replace it with a default pic of my choosing?
I am converting the string to image data using Convert.FromBase64String (string encoded) in c#.
I assume that you use some API to retrieve the base64 encoded string from an URL?
In that case, you could just dump the retrieved string once to the console and then copy it into your source code and compare this to the string you get in the future. Of course, this will break if the facebook API you use decides to deliver a different icon, in which case you would have to dump the new "unknown user" thumbnail.
string encoded = ... // however you obtain your thumbnail
print encoded; // dump the string to the console once. remove this statement later
if (encoded == "...here comes the (rather large) string you just copied")
encoded = "...here comes some other image you like to use, encoded as string";
...
Not very elegant, but at least easy to implement.
I suppose, if an error image (e.g. the "red question-mark" image) is predictably returned when no profile picture exists, you could simply test for that case and replace with another image of your choosing. You may choose to store the red question-mark image as a resource and then compare its Base64 string to the Base64 of each image returned from your requests.
In that case, the pivotal bit of code might look something like this (assuming you've already stored the image's Base64 string in a resource):
ResourceManager rm =
new ResourceManager("ExampleAppData", typeof(ExampleApp).Assembly);
String errorImageBase64 = rm.GetString("ErrorImageBase64");
// the image you get from your request
String resultImageBase64 = GetProfileImageBase64();
Image missingProfile;
if(resultImageBase64.Equals(errorImageBase64))
{
missingProfile = ImageFromBase64String(rm.GetString("MissingProfileBase64"));
}
else
{
missingProfile = ImageFromBase64String(resultImageBase64);
}
References:
http://msdn.microsoft.com/en-us/library/2xsy4hac.aspx
http://ozgur.ozcitak.com/snippets/2009/12/21/base64-encoding-an-image-with-csharp.html
In my experience it was due to a wrong request.
In my case the wrong API query returning Red Questionmark was /{fbId}/picture?g&type=square&height=128&width=128
I solved removing "?g", the working query now is
/{fbId}/picture?type=square&height=128&width=128

Categories