Convert byte[] image to string - c#

MediaFile ficheiro;
byte[] image = File.ReadAllBytes(ficheiro.Path);
var file = image.ByteArrayImageToBase64();
string[] x = new string[] { file };
MediaFile is a plugin to get image in gallery
Visually the code does not give me error. But I want to see another way that I can convert the bytes of the image to string.
What would be the most efficient way to convert an array of bytes from an image to a string. I intend to send this image later with a post method. But my difficulty is in conversion because trying to send says that the request is too long. due to ByteArrayImageToBase64

Related

How to convert ImageSourse to NSUrl or CGImage in xamarin ios

I want to convert the ImageSource or image byte array to Xamarin.ios NSUrl or CGImage. How to implement this. I am generating the byte Array from LayoutView like below. So after getting the the byte array I need to convert it to NSUrl or CGImage for printing that layout. From the below code I will get the bytearray.
public byte[] LayoutToImage()
{
var view = UIApplication.SharedApplication.KeyWindow;
UIGraphics.BeginImageContext(view.Frame.Size);
view.DrawViewHierarchy(view.Frame, true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
using (var imageData = image.AsPNG())
{
var bytes = new byte[imageData.Length];
System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
return bytes;
}
}
I am able to print the image on the iOS project resource file, like that I need to print the layout view also.
string fileName = "SampleImg.png";
string localDocUrl = Path.Combine(NSBundle.MainBundle.BundlePath, fileName);var Error = Driver.PrintImageWithURL(new NSUrl(localDocUrl), pSettings);
As Jason said GetImageFromCurrentImageContext returns a UIImage. If you want to convert to CGImage, you can directly use UIImage.CGImage to get CGImage. Converting a byte array to a CGImage also needs to be converted to a UIImage first.

Error converting byte array to Image

I've read images in and saved them in a database in byte[] format. Later I want to retrieve the images and convert them into Image format. I've written the following method:
private List<Image> ConvertByteArraysToImages(List<byte[]> byteDataList)
{
List<Image> retVal = new List<Image>();
int counter = 0;
foreach (byte[] byteData in byteDataList)
{
// Something is wrong here
MemoryStream memstr = new MemoryStream(byteData);
Image img = Image.FromStream(memstr);
retVal.Add(img);
memstr.Dispose();// Just added this
// This works fine, the images appear in the folder
System.IO.File.WriteAllBytes(String.Format(#"C:\dev\test{0}.png", counter), byteData);
counter++;
}
return retVal;
}
I'm calling this method from an action which adds the images to the ViewBag to use in the view.
public ActionResult ViewTicket(Incident ticket)
{
//Read the ticket via the web API
string serialisedJSON = JsonConvert.SerializeObject(ticket.ID);
string response = TicketUtilities.JSONRequestToAPI(serialisedJSON, "GetSingleIncident");
Incident retVal = JsonConvert.DeserializeObject<Incident>(response);
//Convert byte[] to Image and add to ViewBag
List<Image> ScreenshotImagesFullsize = ConvertByteArraysToImages(retVal.Screenshots);
ViewBag.Add(ScreenshotImagesFullsize); //Error here
return View(retVal);
}
When I try to add the images to the ViewBag I get the following error in the browser:
Cannot perform runtime binding on a null reference
Writing the byte arrays to file produces the correct output but I'm not getting a list of Images in my return value. Hovering over retVal in debug mode shows the following:
I passed in two byte arrays and I see 2 objects in retVal, but I also I see the error: "Cannot evaluate expression because the code of the current method is optimized". Why does this occur?
Update: I disabled JIT optimization and now I can see the following:
I can see that the object has correctly acquired properties such as the height and width but the actual data is null.
Do not dispose the stream and do keep at least one reference to it as long as you need the image.
"You must keep the stream open for the lifetime of the Image."
https://msdn.microsoft.com/de-de/library/1kcb3wy4(v=vs.110).aspx
Note that there is no need to manually call dispose on a MemoryStream because it does not have unmanaged resources
So I solved this, the problem turned out not to be the conversion but rather adding Image objects to the view. For some reason adding Image objects to the view does not work, to overcome this I converted the image to a Base64 string
using (MemoryStream m = new MemoryStream())
{
retVal.Img.Save(m, retVal.Img.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string imreBase64Data = Convert.ToBase64String(imageBytes);
retVal.ImgB64 = string.Format("data:image/png;base64,{0}", imreBase64Data);
}

How to get string from dataPackageView.GetDataAsync()

I'm trying to get non-standard-format data from the clipboard using DataPackageView.GetDataAsync. I am stumped on converting the returned system.__ComObject to a string.
Here is the code:
var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();
if (dataPackageView.Contains("FileName"))
{
var data = await dataPackageView.GetDataAsync("FileName");
// How to convert data to string?
}
I am looking for a solution that will work with any non-standard clipboard format. "FileName" is an easily testable format as you can put it on the clipboard by copying a file in Windows Explorer.
In C++/Win32, I can get the clipboard data as follows:
OpenClipboard(nullptr);
UINT clipboarFormat = RegisterClipboardFormat(L"FileName");
HANDLE hData = GetClipboardData(clipboarFormat);
char * pszText = static_cast<char*>(GlobalLock(hData));
GlobalUnlock(hData);
CloseClipboard();
In C++, the clipboard data is just an array of bytes. It must be possible to get the same array of bytes in C#, but I have no clue on unwrapping/converting the system.__ComObject
Edit: Rephrasing the question:
How do I get a string or array of byes out of the system.__ComObject returned by dataPackageView.GetDataAsync(someFormat), where someFormat is an arbitrary clipboard format created by another application?
It is very clear to me how to get the data. The difficult part is using the data that is returned.
The accepted answer must show how to create a string or array of bytes from the "data" returned by
var data = await dataPackageView.GetDataAsync(someFormat);
if you know its a file you can use the following code
var content = Clipboard.GetContent();
IReadOnlyList<IStorageItem> files = await content.GetStorageItemsAsync();
var file = files.First() as StorageFile;
From MSDN article on StandardDataFormats
The DataPackage class supports a number of legacy formats for interoperability between Windows Store apps and desktop apps. To retrieve these formats, you pass one of the following strings to the DataPackageView.GetDataAsync method instead of a value from the StandardDataFormats class.
eg
var content = Clipboard.GetContent();
var data = await content.GetDataAsync("PenData"); //Stream for HGLOBAL corresponding to CF_PENDATA
This article explains how custom dataPackage objects are implemented.
http://www.minddriven.de/index.php/technology/dot-net/c-sharp/winrt-datapackage-custom-objects
The key is to cast the return value of dataPackageView.GetAsync() into an IRandomAccessStream
Here is something that works:
var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();
if (dataPackageView.Contains("FileName"))
{
var data = await dataPackageView.GetDataAsync("FileName");
// convert data to string
var data = await dataPackageView.GetDataAsync("FileName");
var dataObj = data as IRandomAccessStream;
var stream = dataObj.GetInputStreamAt(0);
IBuffer buff = new Windows.Storage.Streams.Buffer((uint)dataObj.Size);
await stream.ReadAsync(buff, (uint)dataObj.Size, InputStreamOptions.None);
var filePath = Encoding.ASCII.GetString(buff.ToArray());
filePath = filePath.Replace("\0","");//get rid of null characters
}
This should work for any custom data format, not just "FileName". If you do not require a string, you could just use the bytes available from the IRandomAccessStream.

Xamarin IOS Encoding/Decoding Images from and to Base64

I am working on an application for IOS in Xamarin. I have a menu in which I request something called "Doublechecks". These doublechecks have a field with the name "Medication". In a previous working copy of the app, I simply used a string to fill this field, but now we had the idea to, instead of filling this medication field with a string, to fill it with an image. One of the tips I got was to convert a taken or chosen image to base64.
In the menu where I make a new doublecheck I have a button that pops up an actionsheet, where you can choose weather you want to pick an image from your PhotoLibrary, or take a new picture with your camera. When you've taken or chosen a picture, I use the following method to encode it to Base64:
var imageToSend = originalImage.AsJPEG (0.23f).GetBase64EncodedString (NSDataBase64EncodingOptions.None);
Where the originalImage is the image I took/chose. Now, when requesting all doublechecks, I use the following to decode it:
byte[] encodedDataAsBytes = System.Convert.FromBase64String (imageToDisplay);
string decoded = System.Text.Encoding.ASCII.GetString (encodedDataAsBytes);
NSData data = NSData.FromString (decoded, NSStringEncoding.ASCIIStringEncoding);
return UIImage.LoadFromData (data);
The method works up until the return. Somehow, the UIImage is not being constructed, and has its value null, even though the 'data' contains the decoded string.
I have searched several threads and fora, but without much avail. Any help would be much appreciated.
Why are you converting the base64 decoded data into a string ?
Since you already have the byte array you should be able to simply do:
byte[] encodedDataAsBytes = System.Convert.FromBase64String (imageToDisplay);
NSData data = NSData.FromArray (encodedDataAsBytes);
return UIImage.LoadFromData (data);
NSData method not always a good solution. You can also try following
var rawData = pixelMap.ToByteArray();
using (var provider = new CGDataProvider(rawData, 0, rawData.Length))
{
using (var colorSpace = CGColorSpace.CreateDeviceRGB())
{
var cgImage = new CGImage(
pixelMap.Width,
pixelMap.Height,
pixelMap.BitsPerComponent,
pixelMap.BytesPerPixel * ByteToBit,
pixelMap.BytesPerPixel * pixelMap.Width,
colorSpace,
CGBitmapFlags.ByteOrderDefault,
provider,
null,
true,
CGColorRenderingIntent.Default
);
return ImageSource.FromStream(() => UIImage.FromImage(cgImage).AsPNG().AsStream());
}
}
Check out my library and samples for more info about both Android and iOS bitmap from/to 2d pixel map.
https://github.com/enginkirmaci/Imaging-Library

Get the distorted/encrypted image from encrypted data bytes of an image

I have encrypted the data bytes of an image file (.jpeg/.png) using Simplified DES. But after encryption, the image file cannot be reconverted to an image as it loses it's original file structure. Is there any way by which I can use these encrypted data bytes to convert to an image file? Here is a glimpse of my C# code:
Console.WriteLine("Please enter the RGB/GRAY/BINARY image path: ");
string path = Console.ReadLine();
byte []arrayPT = Conversion.Convert.ImageToBinary(path); // Get the binary data
byte []arrayCT = new byte[arrayPT.Length];
int i = 0;
foreach (byte element in arrayPT)
{
arrayCT[i] = ob.Encrypt(element);
/* I want to use the contents of the arrayCT[] and convert to an image */
Console.Write("{0}", arrayCT[i]);
i++;
}
With your current approach you are encrypting the image header along with the contents, it will not be considered an image anymore.
If you do not need to hide the fact that it is an image nor its width×height, the approach I would take is the following:
Get the original image into a Bitmap object
This should give you access to the decompressed image as byte array (Bitmapdata)
Encrypt the byte array
Create a new Bitmap object with the same width and height of the original
Import the encrypted bytes into the new Bitmap bytes
Save the image in a new file with the same format as the input image
Check Bitmapdata for a way to work with the image bytes efficiently.

Categories