I'm building an API that among other things allows users to change their photo. This photo is sent in as a base64 string and I want to be able to validate that it's an actual .jpeg or .png format.
Since System.Drawing is missing in .NET core i'm not sure how to go about doing this. Before i could have simply used something like
public Image Base64ToImage(string base64String)
{
// Convert base 64 string to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
// Convert byte[] to Image
using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
Image image = Image.FromStream(ms, true);
return image;
}
}
and then gone from there to check what i needed about the Image.
Any help would be appreciated
When you don't have System.Drawing I would look at the actual bytes instead to see if they match the JPEG or PNG file standard.
For a PNG file the first eight bytes always contains the following decimal values: 137 80 78 71 13 10 26 10 (Source)
A JPEG file is more complex but it can be done as well. The first two bytes, at least, seems to always be 0xFF 0xD8 (Source). Read a bit more about the file structure to get better comparison values.
Based on this you can do a simple comparison on the bytes in your imageBytes array.
Related
I pick an image from the device and it's mirrored that's normal but I want to flip it horizontally before send it to API as to preview it after that normal not mirrored and do this on base64 string image.
You have not posted all the information however.
In Xamarin Forms Platform you can use FFImageLoading plugin which supports the transformation you are looking for. It support:
FlipTransformation
RotateTransformation
Follow the link to find their implementation here:
https://github.com/luberda-molinet/FFImageLoading/blob/master/samples/ImageLoading.Forms.Sample/Shared/Pages/Transformations/FlipTransformationPage.xaml
Your question did not explain clearly what you want to do.You can update it with more detail you want to conver what type to what type First.Whatever, I show a possible answer.
image path to base64 string:
// provide read access to the file
FileStream fs = new FileStream(media.Path, FileMode.Open,FileAccess.Read);
// Create a byte array of file stream length
byte[] ImageData = new byte[fs.Length];
//Read block of bytes from stream into the byte array
fs.Read(ImageData,0,System.Convert.ToInt32(fs.Length));
//Close the File Stream
fs.Close();
string _base64String = Convert.ToBase64String (ImageData);
base64 string to byte[]:
byte[] data = Convert.FromBase64String (FileRespone);
I used to flip the image as bitmap not Base64
in Android
https://acomputerengineer.wordpress.com/2016/06/07/flip-imagebitmap-horizontally-and-vertically-in-android/
in IOS:
How to flip UIImage horizontally?
UIImage sourceImage = uiImage;//[UIImage imageNamed: #"whatever.png"];
UIImage flippedImage = sourceImage.GetImageFlippedForRightToLeftLayoutDirection();
//[UIImage imageWithCGImage: sourceImage.CGImage scale: sourceImage.scale orientation: UIImageOrientationUpMirrored];
I work on a project where i need to process a image i receive from a socket and to display it.
I'm getting the image in jpeg format,and i cannot just use the Image.FromStream()); method for retrieving the image,because it contains more data and i want to process it while i'm reading the data-for efficiency reasons.(Basically what i want is to read the image from the stream manually).
Is there any source which explaines how these image are stored in the MemoryStream?
The MemoryStream is built on a byte[] buffer,i resuse the same buffer also and i do not create a new MemoryStream everytime the method called.
A sample of code:
private byte[] BlockToJpeg()
{
Bitmap block=new Bitmap("...");
MemoryStream ms=new MemoryStream();
block.Save(ms, ImageFormat.Jpeg);
return ms.GetBuffer();
}
So the call would look like this
byte[] buffer=BlockToJpeg();
sck.Send(buffer);//sending the buffer...not the full code because this is not our problem.
Now in the Reciver side,when i'll get that buffer:
Byte[] RecieveBuffer=sck.Recieve();//again,kind of pseudo code,because this is not the relevant part.
i have to processes it's pixels,so i'll prefer to read them from the byte[] array one by one manually...
Is there any structure for reading this(in our case-reading a jpeg image stored as byte array)?
For example- first 4 bytes are width,second are height...3rd are PixelFormat and the rest are the pixels values...or somthing...?
Thanks.
jpeg is type of compression method usually on images.
you can read more about it here:http://www.ams.org/samplings/feature-column/fcarc-image-compression
I download the SevenZipSharp Lib in order to compress some files.
I used this in order to compress a file :
var libPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "7-zip", "7z.dll");
SevenZip.SevenZipCompressor.SetLibraryPath(libPath);
SevenZip.SevenZipCompressor compressor = new SevenZipCompressor();
compressor.CompressFiles(#"C:\myTestFile.mdf", new string[] { #"C:\myTestFileCompressed.7z" });
With this, my file is compressed whitout problem. I can decompressed it.
Now...i would like to compress the same file, but, instead of compress directly the file, i would like to :
Read the file in a string. Yes, in a string, and not in a byte[].
Convert my string to byte[]
Compress the byte[] to another byte[].
Here is my try :
string strToCompress = File.ReadAllText(#"C:\myTestFile.mdf");
SevenZipCompressor compressor = new SevenZipCompressor();
byte[] byteArrayToCompress = Encoding.ASCII.GetBytes(text);
MemoryStream stream = new MemoryStream(byteArrayToCompress);
MemoryStream streamOut = new MemoryStream();
compressor.CompressStream(stream, streamOut);
string strcompressed = Encoding.ASCII.GetString(streamOut.ToArray());
File.WriteAllText(#"C:\myfileCompressed.7z",strcompressed);
My problem is very simple :
If i compare the size produced by these 2 methods, it's 3 603 443 bytes vs 3 604 081 bytes.
In addition, i cannot uncompressed the file produced by the second method.
Maybe it's because i used ASCII encoding, but my file to compress is not a Text, it's a binary file.
Anyone could explain me how solving it please ? I need to read my file to a string and compress it. ( i don't want to read the file directly to a byte[]).
Thanks a lot,
Best regards,
Nixeus
You cannot put binary data into a string, not every byte value has a Unicode codepoint. Using ASCII encoding will similarly always cause irretrievable data loss, it only has characters for byte values 0 through 127, higher values will produce a ?
You certainly can convert a byte[] to a string, it needs to be encoded. The standard encoding that's used for that is available in .NET from the Convert.ToBase64String() method. You recover the byte[] again with Convert.FromBase64String(). Inevitably it won't be as compact, it will be 4/3 bigger as the original data in a byte[].
You can never produce a valid .7z archive that way, it of course uses the most compact possible storage and that is bytes. You must pass a FileStream to the CompressStream() method.
i'm working on a website that takes its data from a web service. Our Android developer gave me a Base64 string like this.
iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4CAYAAAB1ovlvAAAABHNCSVQICAgIf. . . . . . . . . .
I'm saving this string to my database. I would like to know how I can convert this to an image.
Here is the solution for you
public Image Base64ToImage(string base64String)
{
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes, 0,imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
return image;
}
If you're showing it in a web page (You added asp.net as one of your tags so I'm assuming this is for the web) you can cheat and do this:
<img src="data:image/png;base64,<%=base64String%>"/>
This assumes that the image is a png, otherwise change it to image/jpg or whatever.
The downside is this stops the image being cached. So in practice the solution by #Sachin is more practical. This way is just neat if you want to avoid saving the files for whatever reason (or just want a 'I need it to work now' solution)
I have convert one image into base64 string and that output same with online website.
But the same image when I convert it from Android is different.
Can you please explain why C# and Android base64 strings are different for the same image.
C#.NET Code
string cImagePath = #"G:\bg-listing.png";
byte[] imagebyte = StreamFile(cImagePath);
String result = System.Convert.ToBase64String(imagebyte);
System.IO.StreamWriter outFile;
try
{
outFile = new System.IO.StreamWriter(Application.StartupPath + "//image2base641.txt",
false,
System.Text.Encoding.Default);
outFile.Write(result.ToString());
outFile.Close();
}
catch (System.Exception exp)
{
// Error creating stream or writing to it.
System.Console.WriteLine("{0}", exp.Message);
}
Android Code
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(), R.drawable.image);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
bitmapOrg.compress(Bitmap.CompressFormat.JPEG, 100, bao);
byte [] ba = bao.toByteArray();
String ba1=Base64.encodeToString(ba,Base64.DEFAULT);
Both image base64 are different.
Please help me.
There are many variants of base 64, involving line length, padding, check sums, etc. The Wikipedia article on Base64 has a nice table of variants.
My guess is that C# and Android are simply using different variants.
EDIT Based on your updated post, there are a couple of other possibilities:
Android may be modifying the .jpg file when it packages it up as a resource (however, while the resource packager is extremely aggressive regarding compression, this is probably not the case);
Android may be re-encoding the image differently than the original (two .jpg files can represent the same pixel values and not be byte-for-byte identical)
A better test would be to skip (in the Android code) the conversion from a resource to a Bitmap and back to a .jpg encoding. Just open the resource as a stream, read it directly into a byte array, and encode that in base 64.