Im using the following code to get the signature from the signature pad, But any value doesn't come.
try {
var signature = padView.GetImage (Acr.XamForms.SignaturePad.ImageFormatType.Png);
using (BinaryReader br = new BinaryReader (signature)) {
var result = br.ReadBytes ((int)signature.Length);
}
} catch (Exception ex) {
// Helper_ErrorHandling.SendErrorToServer (ex);
}
Am I ding it wrong, Also how do i convert this to a base64 string
?
I'm not too familiar with the Xamarin Forms Signature Pad, but if you're looking for a way to convert a Stream to as base64 string, try this:
[...]
string base64String;
using (var memoryStream = new MemoryStream())
{
signature.CopyTo( memoryStream );
var byteArray = memoryStream.ToArray();
base64String = Convert.ToBase64String( byteArray );
}
EDIT: you can most of the time skip the copy, if you check if signature is already a MemoryStream...
[...]
string base64String;
var signatureMemoryStream = signature as MemoryStream;
if (signatureMemoryStream == null)
{
signatureMemoryStream = new MemoryStream();
signature.CopyTo( signatureMemoryStream );
}
var byteArray = signatureMemoryStream.ToArray();
base64String = Convert.ToBase64String( byteArray );
Using the most current PCL compliant Xamarin package :
acr-xamarin-forms
This method works like a charm!
private string ConvertSignatureToBase64()
{
try
{
byte[] data;
if(Device.OS == TargetPlatform.iOS)
{
var img = SignaturePad.GetImage(Acr.XamForms.SignaturePad.ImageFormatType.Jpg);
var signatureMemoryStream = new MemoryStream();
img.CopyTo(signatureMemoryStream);
data = signatureMemoryStream.ToArray();
}
else
{
var img = SignaturePad.GetImage(Acr.XamForms.SignaturePad.ImageFormatType.Jpg);
var signatureMemoryStream = (MemoryStream)img;
data = signatureMemoryStream.ToArray();
}
return Convert.ToBase64String(data);
}
catch(Exception ex)
{
return ex.ToString();
}
}
Related
I have asp.net mvc application which has file upload functionality. While uploading the file, I am performing few validations on the uploaded content before moving it to database and file system location.
Here goes my code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddImage([Bind(Include = "image,ImageName,ImageType,CountryId,Keyword,Source,Copyright,Description")] CreateImageViewModel model)
{
if (!this.ModelState.IsValid)
{
return View("Images");
}
if (model != null && model.image.ContentType.Contains(Constants.Image) && !ValidateUploadedImageContent(model.image, model.image.FileName))
{
var dto = new ImageDTO();
model.FilePath = model.image.FileName;
dto.ImageFile = model.image;
dto.Name = model.ImageName;
dto.FilePath = model.image.FileName;
dto.FileType = Path.GetExtension(model.FilePath);
dto.ImageType = model.ImageType;
dto.CountryId = model.CountryId;
dto.Keyword = model.Keyword;
dto.Source = model.Source;
dto.Copyright = model.Copyright;
dto.Description = model.Description;
dto.CreatedBy = UserDto.emailId;
try
{
_imageService.SaveImage(dto);
}
catch (Exception ex)
{
if (ex.Message.Equals(Constants.InvalidImageType))
return GetSafeRedirect(Url.Action("AddImage", model) + "#onload-errors");
throw ex;
}
return RedirectToAction(Constants.Actions.Images.ToString());
}
else
{
return GetSafeRedirect(Url.Action("AddImage", model) + "#onload-errors");
}
}
private bool ValidateUploadedImageContent(HttpPostedFileBase uploadedFile, string imageFileName)
{
if (Path.GetExtension(imageFileName).Equals(".svg", StringComparison.OrdinalIgnoreCase))
{
if (uploadedFile.ContentLength > 0)
{
byte[] data;
//using (Stream inputStream = uploadedFile.InputStream)
//{
Stream inputStream = uploadedFile.InputStream;
var memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
data = memoryStream.ToArray();
//}
var parsedData = Encoding.UTF8.GetString(data, 0, data.Length).TrimEnd('\0');
var result = parsedData.ContainsAny(Constants.InsecureStrings, StringComparison.CurrentCultureIgnoreCase);
return result;
}
}
return false;
}
Here in the above method: ValidateUploadedImageContent(), I tried to dispose the stream object with the help of using statement but I found that if I keep the below code in the method: ValidateUploadedImageContent(), then in that case post validation process, I found on debugging that the ContentLength property is set with 0 value and finally corrupted image gets saved in the file system location.
Updated :
private bool ValidateUploadedImageContent(HttpPostedFileBase uploadedFile, string imageFileName)
{
if (Path.GetExtension(imageFileName).Equals(".svg", StringComparison.OrdinalIgnoreCase))
{
if (uploadedFile.ContentLength > 0)
{
byte[] data;
using (Stream inputStream = uploadedFile.InputStream)
{
Stream inputStream = uploadedFile.InputStream;
var memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
data = memoryStream.ToArray();
}
var parsedData = Encoding.UTF8.GetString(data, 0, data.Length).TrimEnd('\0');
var result = parsedData.ContainsAny(Constants.InsecureStrings, StringComparison.CurrentCultureIgnoreCase);
return result;
}
}
return false;
}
Can anyone help me to know how to fix this issue?
First to address your issue, which I now understand is that after the call to ValidateUploadedImageContent the image stream is invalid.
That is because the stream gained from the HttpPostedFileBase is "read-only sequential (non-seekable)" as detailed in this SO answer. This explains why the stream's ContentLength is 0 - the stream has been consumed by the validation call.
If you have flexibility with the ImageDTO class, modifying the validation method such that it returns the image bytes would be a workaround.
For example,
// on success, buffer contains the image data. Otherwise it is null.
private bool ValidateUploadedImageContent(
out byte[] buffer,
HttpPostedFileBase uploadedFile,
string imageFileName)
{
buffer = null;
if (Path.GetExtension(imageFileName).Equals(".svg", StringComparison.OrdinalIgnoreCase))
{
if (uploadedFile.ContentLength > 0)
{
var reader = new BinaryReader(inputStream);
buffer = reader.ReadBytes((int)uploadedFile.ContentLength);
var parsedData = Encoding.UTF8.GetString(buffer, 0, buffer.Length).TrimEnd('\0');
return parsedData.ContainsAny(Constants.InsecureStrings, StringComparison.CurrentCultureIgnoreCase);
}
}
return false;
}
I've used BinaryReader to simplify the code.
Then back to the calling method,
byte[] imageBuffer = null;
if (model != null && model.image.ContentType.Contains(Constants.Image)
&& !ValidateUploadedImageContent(out imageBuffer, model.image, model.image.FileName)) {
var dto = new ImageDTO();
using(var imageStream = new MemoryStream(imageBuffer)) {
// pass along imageStream to your ImageDTO and save.
}
}
Again, hopefully you have some flexibility with the ImageDTO class.
How do you convert an image from a path on the user's computer to a base64 string in C#?
For example, I have the path to the image (in the format C:/image/1.gif) and would like to have a data URI like data:image/gif;base64,/9j/4AAQSkZJRgABAgEAYABgAAD.. representing the 1.gif image returned.
Try this
using (Image image = Image.FromFile(Path))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
Get the byte array (byte[]) representation of the image, then use Convert.ToBase64String(), st. like this:
byte[] imageArray = System.IO.File.ReadAllBytes(#"image file path");
string base64ImageRepresentation = Convert.ToBase64String(imageArray);
To convert a base64 image back to a System.Drawing.Image:
var img = Image.FromStream(new MemoryStream(Convert.FromBase64String(base64String)));
Since most of us like oneliners:
Convert.ToBase64String(File.ReadAllBytes(imageFilepath));
If you need it as Base64 byte array:
Encoding.ASCII.GetBytes(Convert.ToBase64String(File.ReadAllBytes(imageFilepath)));
This is the class I wrote for this purpose:
public class Base64Image
{
public static Base64Image Parse(string base64Content)
{
if (string.IsNullOrEmpty(base64Content))
{
throw new ArgumentNullException(nameof(base64Content));
}
int indexOfSemiColon = base64Content.IndexOf(";", StringComparison.OrdinalIgnoreCase);
string dataLabel = base64Content.Substring(0, indexOfSemiColon);
string contentType = dataLabel.Split(':').Last();
var startIndex = base64Content.IndexOf("base64,", StringComparison.OrdinalIgnoreCase) + 7;
var fileContents = base64Content.Substring(startIndex);
var bytes = Convert.FromBase64String(fileContents);
return new Base64Image
{
ContentType = contentType,
FileContents = bytes
};
}
public string ContentType { get; set; }
public byte[] FileContents { get; set; }
public override string ToString()
{
return $"data:{ContentType};base64,{Convert.ToBase64String(FileContents)}";
}
}
var base64Img = new Base64Image {
FileContents = File.ReadAllBytes("Path to image"),
ContentType="image/png"
};
string base64EncodedImg = base64Img.ToString();
You can easily pass the path of the image to retrieve the base64 string
public static string ImageToBase64(string _imagePath)
{
string _base64String = null;
using (System.Drawing.Image _image = System.Drawing.Image.FromFile(_imagePath))
{
using (MemoryStream _mStream = new MemoryStream())
{
_image.Save(_mStream, _image.RawFormat);
byte[] _imageBytes = _mStream.ToArray();
_base64String = Convert.ToBase64String(_imageBytes);
return "data:image/jpg;base64," + _base64String;
}
}
}
Hope this will help.
You can use Server.Map path to give relative path and then you can either create image using base64 conversion or you can just add base64 string to image src.
byte[] imageArray = System.IO.File.ReadAllBytes(Server.MapPath("~/Images/Upload_Image.png"));
string base64ImageRepresentation = Convert.ToBase64String(imageArray);
This code works well with me on DotNet Core 6
using (Image image = Image.FromFile(path))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, ImageFormat.Jpeg);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
// In my case I didn't find the part "data:image/png;base64,", so I added.
return $"data:image/png;base64,{base64String}";
}
}
That way it's simpler, where you pass the image and then pass the format.
private static string ImageToBase64(Image image)
{
var imageStream = new MemoryStream();
try
{
image.Save(imageStream, System.Drawing.Imaging.ImageFormat.Bmp);
imageStream.Position = 0;
var imageBytes = imageStream.ToArray();
var ImageBase64 = Convert.ToBase64String(imageBytes);
return ImageBase64;
}
catch (Exception ex)
{
return "Error converting image to base64!";
}
finally
{
imageStream.Dispose;
}
}
Based on top voted answer, updated for C# 8. Following can be used out of the box. Added explicit System.Drawing before Image as one might be using that class from other namespace defaultly.
public static string ImagePathToBase64(string path)
{
using System.Drawing.Image image = System.Drawing.Image.FromFile(path);
using MemoryStream m = new MemoryStream();
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
tring base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
The following piece of code works for me:
string image_path="physical path of your image";
byte[] byes_array = System.IO.File.ReadAllBytes(Server.MapPath(image_path));
string base64String = Convert.ToBase64String(byes_array);
The reverse of this for the googlers arriving here (there is no SO quesion/answer to that)
public static byte[] BytesFromBase64ImageString(string imageData)
{
var trunc = imageData.Split(',')[1];
var padded = trunc.PadRight(trunc.Length + (4 - trunc.Length % 4) % 4, '=');
return Convert.FromBase64String(padded);
}
Something like that
Function imgTo64(ByVal thePath As String) As String
Dim img As System.Drawing.Image = System.Drawing.Image.FromFile(thePath)
Dim m As IO.MemoryStream = New IO.MemoryStream()
img.Save(m, img.RawFormat)
Dim imageBytes As Byte() = m.ToArray
img.Dispose()
Dim str64 = Convert.ToBase64String(imageBytes)
Return str64
End Function
Encrypt.cs
BitmapImage bitmapImage = new BitmapImage(new Uri(this.BaseUri,#"D:\Others\Quotes\1.jpg"));
var plainString = bitmapImage;
string key = txtkey.Text; // Key
string encryptedString = await EncryptStringHelper(plainString.ToString(), key); // Encrypt method and get string
txbencrypt.Text = encryptedString;
Decrypt.cs
string encryptedString = txbencrypt.Text; // Encrypt text
string key = txtkey.Text; // Same key
string decryptedString = await DecryptStringHelper(encryptedString, key);
imgoutput.Source = decryptedString;
private Task<string> EncryptStringHelper(string plainString, string key)
{
try
{
var hashKey = GetMD5Hash(key);
var decryptBuffer = CryptographicBuffer.ConvertStringToBinary(plainString, BinaryStringEncoding.Utf8);
var AES = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
var symmetricKey = AES.CreateSymmetricKey((IBuffer)hashKey);
var encryptedBuffer = CryptographicEngine.Encrypt(symmetricKey, decryptBuffer, null);
var encryptedString = CryptographicBuffer.EncodeToBase64String(encryptedBuffer);
return Task.Run(() =>
{
return encryptedString;
});
}
catch (Exception ex)
{
return null;
}
}
public Task<string> DecryptStringHelper(string encryptedString, string key)
{
try
{
var hashKey = GetMD5Hash(key);
IBuffer decryptBuffer = CryptographicBuffer.DecodeFromBase64String(encryptedString);
var AES = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
var symmetricKey = AES.CreateSymmetricKey((IBuffer)hashKey);
var decryptedBuffer = CryptographicEngine.Decrypt(symmetricKey, decryptBuffer, null);
string decryptedString = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decryptedBuffer);
return Task.Run(() =>
{
return decryptedString;
});
}
catch (Exception ex)
{
return null;
}
}
I develop Universal windows application(UWP) then tried encrypt and decrypt to image file, but i convert image to encrypt text then i couldn't convert when i decrypt that text into image. So how do i do that?
You would want to convert your base 64 string to a byte array, and then create the ImageSource from that.
byte[] data = Convert.FromBase64String(base64string);
if (data.caseImage.Count() > 1)
{
MemoryStream ms = new MemoryStream(data.caseImage, 0, data.caseImage.Length);
BitmapImage img = new BitmapImage();
var ras = ms.AsRandomAccessStream();
await img.SetSourceAsync(ras);
imgCase.Source = img;
}
with imgCase being a Xaml image.
in terms of initially creating the base64string you would want to do something like this:
Converting BitMapImage to ImageSource:
BitmapImage bitmapCamera = new BitmapImage();
bitmapCamera.SetSource(streamCamera);
// Convert the camera bitap to a WriteableBitmap object,
// which is often a more useful format.
int width = bitmapCamera.PixelWidth;
int height = bitmapCamera.PixelHeight;
WriteableBitmap wBitmap = new WriteableBitmap(width, height);
using (var stream = await capturedMedia.OpenAsync(FileAccessMode.Read))
{
wBitmap.SetSource(stream);
}
imgPreview.Source = wBitmap;
And or a StorageFile to Base64String:
byte[] fileBytes = null;
var imageFile = *Your storageFile*;
mimetype = imageFile.ContentType;
filetype = imageFile.FileType;
using (IRandomAccessStreamWithContentType stream = await imageFile.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (DataReader reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
string base64 = Convert.ToBase64String(fileBytes);
Hope this helps.
I need to render svg in my XSL fo in c#.Net which is available in https://fonet.codeplex.com/. I tried to use svg in the xsl-fo but it does not render any pdf and fails silently.
If anybody has found a solution for this issue please help.
I need my pdf report to support svg contents.
Use the below code to add Hander of an image incase of svg extensions
FonetDriver fonetDriver = FonetDriver.Make();
fonetDriver.ImageHandler = SvgImageHandler;
Add the SvgImageHandler Hander
private static byte[] SvgImageHandler(string svgContent)
{
if (svgContent.Contains("http://www.w3.org/2000/svg"))
{
var svgByteAry = Encoding.UTF8.GetBytes(svgContent);
using (var stream = new MemoryStream(svgByteAry))
{
var svgDocument = SvgDocument.Open<SvgDocument>(stream);
using (var memoryStream = new MemoryStream())
{
svgDocument.Draw()
.Save(memoryStream, ImageFormat.Png);
var byteArray = memoryStream.ToArray();
return byteArray;
}
}
}
//Skip if not url based image
if (!Uri.IsWellFormedUriString(svgContent, UriKind.RelativeOrAbsolute))
return null;
if (!ValidateUrlImage(svgContent))
{
ICacheService cacheService = new HttpCache();
return cacheService.Get(Constants.NoImage,
() =>
{
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings[Constants.ImagePath];
var defaultUrl = Path.Combine(baseDirectory, Constants.NoImageFile);
var img = Image.FromFile(defaultUrl);
var imgCon = new ImageConverter();
return (byte[])imgCon.ConvertTo(img, typeof(byte[]));
});
}
return null;
}
Return proper image if the url is valid or pass false so the No Image can be rendered. keeping the code more robust.
private static bool ValidateUrlImage(string absoluteUrl)
{
Uri uri;
if (!Uri.TryCreate(absoluteUrl, UriKind.Absolute, out uri))
{
return true;
}
using (var client = new WebClient())
{
try
{
using (var stream = client.OpenRead(uri))
{
Image.FromStream(stream);
return true;
}
}
catch (Exception)
{
return false;
}
}
}
I want to use C# to convert a byteArray to base64string by using Convert.ToBase64String(), then I want to send this string to save using MySQL by sending post data to a PHP page. My problem is I can't convert this string back to a byteArray using this method as after this string is retrieved from the PHP page (after it got data from MySQL), it tells me that argument on method Convert.FromBase64String() was wrong.
I don't where is problem occurs, how can I solve it?
My code:
public static string BitmapToString(BitmapImage img)
{
try
{
WriteableBitmap bmp = new WriteableBitmap(img);
byte[] byteArray = null;
string str = null;
MemoryStream stream = new MemoryStream();
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
byteArray = stream.ToArray();
str = Convert.ToBase64String(byteArray);
return str;
}
catch (System.Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
return null;
}
public static BitmapImage StringToBitmap(string str)
{
try
{
byte[] byteArray = Convert.FromBase64String(str);
Stream memStream = new MemoryStream(byteArray);
BitmapImage img = null;
MemoryStream stream = new MemoryStream(byteArray);
stream.Seek(0, SeekOrigin.Begin);
img = new BitmapImage();
img.SetSource(stream);
return img;
}
catch (System.Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
return null;
}
Convert.FromBase64String() will work for Convert.ToBase64String() results but there can be inputs in your aplication which not converted to Base64String, those cases might fail.
This is not be a issue with those two methods. Check Convert.ToBase64String() result and what you get when you read it from database.