Why is Base64 string different in C# and Android - c#

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.

Related

flip image in before send it to API as Base64 Xamarin forms

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];

Decode Stream to CSV in Python by Byte (Translate from C# code)

I am trying to consume a streamed response in Python from a soap API, and output a CSV file. The response outputs a string coded in base 64, which I do not know what to do with. Also the api documentation says that the response must be read to a destination buffer-by-buffer.
Here is the C# code was provided by the api's documentation:
byte[] buffer = new byte[4000];
bool endOfStream = false;
int bytesRead = 0;
using (FileStream localFileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write))
{
using (Stream remoteStream = client.DownloadFile(jobId))
{
while (!endOfStream)
{
bytesRead = remoteStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
localFileStream.Write(buffer, 0, bytesRead);
totalBytes += bytesRead;
}
else
{
endOfStream = true;
}
}
}
}
I have tried many different things to get this stream to a readable csv file, but non have worked.
with open('test.csv', 'w') as f: f.write(FileString)
Returns a csv with the base64 string spread over multiple lines
Here is my latest attempt:
with open('csvfile13.csv', 'wb') as csvfile:
FileString = client.service.DownloadFile(yyy.JobId, False)
stream = io.BytesIO(str(FileString))
with open(stream,"rt",4000) as readstream:
csvfile.write(readstream)
This produces the error:
TypeError: coercing to Unicode: need string or buffer, _io.BytesIO
Any help would be greatly appreciated, even if it is just to point me in the right direction. I will be ensure to award the points to whoever is the most helpful, even if I do not completely solve the issue!
I have asked several questions similar to this one, but I have yet to find an answer that works completely:
What is the Python equivalent to FileStream in C#?
Write Streamed Response(file-like object) to CSV file Byte by Byte in Python
How to replicate C# 'byte' and 'Write' in Python
Let me know if you need further clarification!
Update:
I have tried print(base64.b64decode(str(FileString)))
This gives me a page full of webdings like
]�P�O�J��Y��KW �
I have also tried
for data in client.service.DownloadFile(yyy.JobId, False):
print data
But this just loops through the output character by characater like any other string.
I have also managed to get a long string of bytes like \xbc\x97_D\xfb(not actual bytes, just similar format) by decoding the entire string, but I do not know how to make this readable.
Edit: Corrected the output of the sample python, added more example code, formatting
It sounds like you need to use the base64 module to decode the downloaded data.
It might be as simple as:
with open(destinationPath, 'w') as localFile:
remoteFile = client.service.DownloadFile(yyy.JobId, False)
remoteData = str(remoteFile).decode('base64')
localFile.write(remoteData)
I suggest you break the problem down and determine what data you have at each stage. For example what exactly are you getting back from client.service.DownloadFile?
Decoding your sample downloaded data (given in the comments):
'UEsYAItH7brgsgPutAG\AoAYYAYa='.decode('base64')
gives
'PK\x18\x00\x8bG\xed\xba\xe0\xb2\x03\xee\xb4\x01\x80\xa0\x06\x18\x01\x86'
This looks suspiciously like a ZIP file header. I suggest you rename the file .zip and open it as such to investigate.
If remoteData is a ZIP something like the following should extract and write your CSV.
import io
import zipfile
remoteFile = client.service.DownloadFile(yyy.JobId, False)
remoteData = str(remoteFile).decode('base64')
zipStream = io.BytesIO(remoteData)
z = zipfile.ZipFile(zipStream, 'r')
csvData = z.read(z.infolist()[0])
with open(destinationPath, 'w') as localFile:
localFile.write(csvData)
Note: BASE64 can have some variations regarding padding and alternate character mapping but once you can see the data it should be reasonably clear what you need. Of course carefully read the documentation on your SOAP interface.
Are you sure FileString is a Base64 string? Based on the source code here, suds.sax.text.Text is a subclass of Unicode. You can write this to a file as you would a normal string but whatever you use to read the data from the file may corrupt it unless it's UTF-8-encoded.
You can try writing your Text object to a UTF-8-encoded file using io.open:
import io
with io.open('/path/to/my/file.txt', 'w', encoding='utf_8') as f:
f.write(FileString)
Bear in mind, your console or text editor may have trouble displaying non-ASCII characters but that doesn't mean they're not encoded properly. Another way to inspect them is to open the file back up in the Python interactive shell:
import io
with io.open('/path/to/my/file.txt', 'r', encoding='utf_8') as f:
next(f) # displays the representation of the first line of the file as a Unicode object
In Python 3, you can even use the built-in csv to parse the file, however in Python 2, you'll need to pip install backports.csv because the built-in module doesn't work with Unicode objects:
from backports import csv
import io
with io.open('/path/to/my/file.txt', 'r', encoding='utf_8') as f:
r = csv.reader(f)
next(r) # displays the representation of the first line of the file as a list of Unicode objects (each value separated)

Validating a base64 encoded image .NET core

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.

Compressing a file from memory with SevenZipSharp, stranges mistakes

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.

Creating a PNG source from data in memory

Situation:
I am reading a PNG file, encoded with base64 from a server (JSON Format). Works fine.
There is NO direct URL to the ressource (just like: http:... / image.png or simuliar), so i read the data (which is part of a JSON object), decode in from the base64 Encoding and store it in a byte[].
Want i want: Display this PNG on a certain page ( like:
ImageOnPage.Source = myPNG;
)
I cant find a way to make PNG-data to a bitmap. With jpegs i could do something like
using (var stream = new MemoryStream(data, 0, x, true, true)) {
var wbp = new WriteableBitmap(1, 1);
wbp.LoadJpeg(stream);
profileImage.Source = wbp;
}
(sorry, code not testet)
I tried to look around and find the PNG Writer Library - but i still didn't find a way to do something to convert my internal PNG to a useable Bitmap for Setting the Image.Source.
Any help appreciated!

Categories

Resources