php base64_decode not work for c# base64 encode

I am encoding image file with c# base64 function and  when decoded with php (base64_decode) , image file corrupted.
Here are code
string filepath="C:/F2/123.jpg";
byte[] imageBytes = System.IO.File.ReadAllBytes(filepath);
string base64String =  Convert.ToBase64String(imageBytes);

Open in new window


  define('UPLOAD_DIR', 'images/');
  $file = UPLOAD_DIR . time() . '.jpg';
  file_put_contents($file,base64_decode(trim($_POST['img'])));

Open in new window


Both c# and php have different output of base64_Decode ?
Bharpinder SinghDeveloperAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
Both c# and php have different output of base64_Decode ?
No, base64 is base64
 file_put_contents($file,base64_decode(trim($_POST['img'])));

Open in new window

What is it you are expecting this is going to do?
$_POST holds post data - not file data - if you are wanting access to an uploaded file you need to look at the $_FILES array
EDIT
Unless you are expecting a string (base64 encoded) in which case - what does the input string look like.
1
Bharpinder SinghDeveloperAuthor Commented:
I am sending image file as string (base64encode ) from c# application but not created image file through php.

what could be wrong?
0
Chinmay PatelChief Technical NinjaCommented:
Hi Bharpinder,

I am generally not very keen on posting links to StackOverflow but it seems to me here is your exact answer:
https://stackoverflow.com/questions/257462/c-sharp-to-php-base64-encode-decode

Also any specific reason you are using Base64string to transmit an image?

Regards,
Chinmay.
0
Introduction to R

R is considered the predominant language for data scientist and statisticians. Learn how to use R for your own data science projects.

Bharpinder SinghDeveloperAuthor Commented:
Already tried StackOverflow  solution.
Not a specific reason, actually i am new in c# so i found code which sent request with post parameter.
I thought to use that code without altering for file post..
0
Julian HansenCommented:
Please post base64 string.
0
Chinmay PatelChief Technical NinjaCommented:
Hi Bharpinder,

In that case, can you tell us what exactly you are trying to do? We might have a better solution for your requirement.
Image as a Base64 string is inefficient when it comes to transmit, receive,process,store and rendering - i.e. by all means. It is a practice that is generally avoided unless and until you have a really strong business reason to support it.

Regards,
Chinmay.
0
gr8gonzoConsultantCommented:
So am I understanding correctly that you have this situation:
1. C# reads a local image file into memory and then converts it to a Base64 string. (shown in your code)
2. C# then POSTs that string to a PHP script. (not shown)
3. PHP tries to base64_decode() the POSTed string, and save it to a local file. (shown)
4. You try to view the resulting file from step 3 but it's corrupted.

If that's correct, then your problem is probably on step 2. Like Julian said earlier, Base64 is Base64 - there is no difference in the algorithm when C# and PHP handle encoding/decoding. Since your first steps look good, chances are that the image data just isn't being sent correctly to PHP (or maybe you're missing the second URL-encoding step when creating your POST string, which could result in only partial data being seen by PHP). In C#, there's a lot of ways to send an HTTP request, and some are very manual (you have to write most of the code, but you can customize just about any part of the request), and others are very managed (you don't have to write a lot of code, but it's also less customizable). If you want something basic, I'd say do something like this:

string filepath="C:/F2/123.jpg";
byte[] imageBytes = System.IO.File.ReadAllBytes(filepath);
string base64String =  Convert.ToBase64String(imageBytes);

// POST the string (using System.Net)
HttpWebRequest postRequest = (HttpWebRequest)HttpWebRequest.Create("http://...URL for your PHP script..."");
postRequest.Method = "POST";
postRequest.ProtocolVersion = HttpVersion.Version11;
postRequest.ContentType = "application/x-www-form-urlencoded";

// Create the POST data and set the length
byte[] postContent = ASCIIEncoding.ASCII.GetBytes("originalfilepath=" + Server.UrlEncode(filepath) + "&img=" + Server.UrlEncode(base64String));
postRequest.ContentLength = postContent.Length;

// Populate the data in the request
Stream strm = postRequest.GetRequestStream();
strm.Write(postContent, 0, postContent.Length);
strm.Close();

// Now send the request by asking for the response
postRequest.GetResponse();

Open in new window

0
gr8gonzoConsultantCommented:
Also, like Chinmay said, Base64 isn't very efficient. If you think about how long your data would be if you converted your image bytes to binary, you'd have 8 characters for every 1 byte, so if your original image was 100,000 bytes, then you'd have to send 800,000 ones and zeroes to represent the same data. You're basically converting from Base-256 (256 possible values for every byte) to Base-2 (2 possible values for every byte).

So when you encode with Base-64, you're going from Base-256 to Base-64. That means the system has to use a few more bytes to properly represent the same data. Basically, every time you base64-encode something, it adds about 30-33% overhead to the original file size. So a 100,000 byte image might take up 133,0000 bytes when encoded in Base64.

Now, you don't have to use base64 encoding to transmit file data from C# to PHP. C# is capable of acting like a web browser and simply uploading the raw data to a PHP script using the proper encoding and content type. This means you can skip over a bunch of steps in C# and actually save some bandwidth, too. However, if you want to do that, I'd recommend opening up a separate question, since this one is specifically about Base64.
0
Julian HansenCommented:
I agree base64 not optimal but there are valid use cases for it. I am intrigued though as to why it is not converting back correctly - which is why I would like to see the base64 string - there may be some clues.

Usually when a base64 image is embedded in a document it is prefixed like so
<img src="data:image/png;base64, iVBORw0KGgoAAAAN...

Open in new window

If the use case is such that any of that prefix data is included in the string it would explain why the data is not converting back - but to be sure we would need to see the string.
0
Bharpinder SinghDeveloperAuthor Commented:
Hello Julian,

I have attached the string which is converted by
string base64String =  Convert.ToBase64String(imageBytes);
In the mean time i am trying another solutions.
0
gr8gonzoConsultantCommented:
Well, his original question shows the initial conversion, so it's doubtful he would prepend HTML or any contextual prefixes. However, if he didn't set up his POST correctly, then the data would either not get seen at all (e.g. if he didn't specify the correct content type), or could have been cut short (e.g. he didn't URL-encode the data and the first un-encoded + character would be interpreted as a space rather than a + character, which would result in an corrupted image).

Seeing the code that sends the data over is the more critical missing part here, I think.
0
Bharpinder SinghDeveloperAuthor Commented:
Sorry forgot to upload attachment
server.txt
0
Bharpinder SinghDeveloperAuthor Commented:
I just saved the $_POST['img'];
I mean posted data into txt file , which confirms that string generated by c# is same which received at php script. attached in text file
It seems issue is while generating base64 string.
Is there any role of UTF8 or ASCIIsome thing like..?
im.txt
0
Bharpinder SinghDeveloperAuthor Commented:
This may be more helpful to find the issue.

One thing just strikes in my mind that in first step i am getting image from webcam which then saved to local path.
Immediately that path are reading to prepare base64 string.

is it possible file readed by step 2 before it was fully saved to local storage??
Here is the complete code.

	string ran=DateTime.Now.ToString("d-M-y-HH-mm-ss");
      string filepath="C:/F2/"+ran+".jpg";
      webCameraControl.GetCurrentImage().Save(filepath);
      byte[] imageBytes = System.IO.File.ReadAllBytes(filepath);
   string base64String =  Convert.ToBase64String(imageBytes);
   

Open in new window

0
gr8gonzoConsultantCommented:
Bharpinder,

It depends if the GetCurrentImage() or Save() routines are asynchronous. If they are, then there's a possibility that the ReadAllBytes() call is being executed before the image is finished saving (it also depends on what file access / sharing mode is specified by the save).

However, your text files confirm what I have been saying - you did not URL-encode your base64 data before using it in your POST, so the + characters are being treated as spaces instead of being treated as + characters. That is the problem.

See my earlier example, where I specify this part in the code:
....."&img=" + Server.UrlEncode(base64String))

You NEED to URL-encode your base64-encoded data before using it in your POST data. Otherwise, the data is being changed before it reaches PHP.
0
Julian HansenCommented:
@Gr8gonzo - I understand but if I have learned one thing on these forums is never take anything for granted.

I decoded the file - it does not appear corrupted - it has a PNG header on the file.

The image opens as a black square (see below)- what should the image look like?decoded.png
0
Bharpinder SinghDeveloperAuthor Commented:
I modified the code to pass static path of images (which is already created on local storage)

Image attached
Then i generated the base64 output (attached in file server.txt)
Then i uploaded the same file at http://freeonlinetools24.com/base64-image to generate base64 string
Both strings are different.
I don't know why c# function generating different string
You can check the code

   	string filepath="C:/F2/15-5-18-20-59-19.jpg";
    byte[] imageBytes = System.IO.File.ReadAllBytes(filepath);
   string base64String =  Convert.ToBase64String(imageBytes);
   File.WriteAllText("C:/F2/server.txt",base64String);

Open in new window

15-5-18-20-59-19.jpg
server.txt
onlinegen.txt
0
gr8gonzoConsultantCommented:
Bharpinder, I'm already telling you what the problem is.

Regarding this recent test - they're the same strings. They just have slightly different formatting. If you eliminate all the different whitespace and then compare, you'll see they're the same. This is the result after I eliminated all whitespace and then reformatted the data with line breaks at the 80-character mark for easier viewing:

start and end of both files side-by-side

$ cat server.txt | openssl md5
(stdin)= 3316792755ea685f5b563542ee6f3c59

$ cat onlinegen.txt | openssl md5
(stdin)= 3316792755ea685f5b563542ee6f3c59

There is literally no difference in the base64 strings being generated. You even showed us the im.txt and the server.txt in your earlier test and they were the same strings except that you hadn't url-encoded your POST variable, so PHP saw spaces instead of + characters, which is the reason for your corrupted data.

If you URL encode your data before posting it, it will fix the problem. (At least this specific problem)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Bharpinder SinghDeveloperAuthor Commented:
let me try with urlencode
is it work with HttpUtility.UrlEncode(base64String);
?
server.UrlEncode did not resolved (didn't find the class or dll file)
0
gr8gonzoConsultantCommented:
You can also use System.Uri.EscapeDataString to do it:
System.Uri.EscapeDataString(base64String)

If it still doesn't work after that, please post your full C# code.

Sorry about the confusion with Server.UrlEncode - I was working on an old ASP page that had been updated to ASP.NET, so that syntax was fresh in my mind. In .NET, there's a dozen ways to do the same thing.
0
Bharpinder SinghDeveloperAuthor Commented:
issue was with urlencode.

actually in my case i was using custom class to send http request which was already urldecoded all post variables (so i need to urlencode).
other side i removed urldecode from php script and its worked..
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.