简体   繁体   中英

Encode and Decode - JPG to base64

I'm developing a Windows Phone Application which uploads a user selected photo to a server using PHP. For this, I'm trying to convert the image to base64 and POST it to PHP where it is decoded back to JPG image.

The base64 string is successfully posted to the PHP but I always get a corrupted JPG file instead of the original image at the server (meaning that there is some error in encoding/decoding of the image).

The C# code for Application is:

public partial class SamplePage : PhoneApplicationPage
    {
        public SamplePage()
        {
            InitializeComponent();
        }

        PhotoChooserTask selectphoto = null;

        private void SampleBtn_Click(object sender, RoutedEventArgs e)
        {
            selectphoto = new PhotoChooserTask();
            selectphoto.Completed += new EventHandler<PhotoResult>(selectphoto_Completed);
            selectphoto.Show();
        }

        void selectphoto_Completed(object sender, PhotoResult e)
        {
            if (e.TaskResult == TaskResult.OK)
            {
                BinaryReader reader = new BinaryReader(e.ChosenPhoto);
                image1.Source = new BitmapImage(new Uri(e.OriginalFileName));
                txtBX.Text = e.OriginalFileName;

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://"+QR_Reader.MainPage.txtBlck+"/beamer/saveimage.php");
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";

                Stream photoStream = ImageToStream(image1);
                BitmapImage bimg = new BitmapImage();
                bimg.SetSource(photoStream); //photoStream is a stream containing data for a photo

                byte[] bytearray = null;
                using (MemoryStream ms = new MemoryStream())
                {
                    WriteableBitmap wbitmp = new WriteableBitmap(bimg);
                    wbitmp.SaveJpeg(ms, wbitmp.PixelWidth, wbitmp.PixelHeight, 0, 100);
                    ms.Seek(0, SeekOrigin.Begin);
                    bytearray = ms.GetBuffer();
                }
                string str = Convert.ToBase64String(bytearray);

                string postData = String.Format("image={0}", str);   

                // Getting the request stream.
                request.BeginGetRequestStream
                (result =>
                {
                    // Sending the request.
                    using (var requestStream = request.EndGetRequestStream(result))
                    {
                        using (StreamWriter writer = new StreamWriter(requestStream))
                        {
                            writer.Write(postData);
                            writer.Flush();
                        }
                    }

                    // Getting the response.
                    request.BeginGetResponse(responseResult =>
                    {
                        var webResponse = request.EndGetResponse(responseResult);
                        using (var responseStream = webResponse.GetResponseStream())
                        {
                            using (var streamReader = new StreamReader(responseStream))
                            {
                                string srresult = streamReader.ReadToEnd();
                            }
                        }
                    }, null);
                }, null);

            }  // end of taskresult == OK           
        }  // end of select photo completed

        private Stream ImageToStream(Image image1)
        {
            WriteableBitmap wb = new WriteableBitmap(400, 400);

            wb.Render(image1, new TranslateTransform { X = 400, Y = 400 });

            wb.Invalidate();
            Stream myStream = new MemoryStream();

            wb.SaveJpeg(myStream, 400, 400, 0, 70);

            return myStream;
        }
    }  // End of Class

The PHP code at the server to decode and save image is:

<?php
function base64_to_image( $imageData, $outputfile ) {
    // encode & write data (binary)
    $ifp = fopen( $outputfile, "wb" );

    fwrite( $ifp, base64_decode( $imageData ) );
    fclose( $ifp );
    // return output filename 
    return( $outputfile );
}       

if (isset($_POST['image'])) {
    base64_to_image($_POST['image'], "img.jpg");
}
else
    die("no image data found");
?>

I don't know what is wrong here. I've been searching for hours to do this and I'm still failing.

Please help me.

EDIT: I just figured out that I always get the same base64 string irrespective of any image that I choose. This is what is get after base64 conversion: http://textuploader.com/?p=6&id=vWZy

I am really puzzled now. I'm getting the same output for each and very image. I don't know why this is happening.

I really want to do this, and I'm stuck here, at base64 encoding. Please help me.

It may not be all of the problem, but this code is broken:

byte[] bytearray = null;
using (MemoryStream ms = new MemoryStream())
{
    WriteableBitmap wbitmp = new WriteableBitmap(bimg);
    wbitmp.SaveJpeg(ms, wbitmp.PixelWidth, wbitmp.PixelHeight, 0, 100);
    ms.Seek(0, SeekOrigin.Begin);
    bytearray = ms.GetBuffer();
}

By using GetBuffer , you'll get the underlying buffer which may well be bigger than the real data. You can use ToArray instead - and you don't need to "rewind" the stream before using either GetBuffer or ToArray :

byte[] bytearray = null;
using (MemoryStream ms = new MemoryStream())
{
    WriteableBitmap wbitmp = new WriteableBitmap(bimg);
    wbitmp.SaveJpeg(ms, wbitmp.PixelWidth, wbitmp.PixelHeight, 0, 100);
    bytearray = ms.ToArray();
}

If that doesn't work, you should take a close look at the before and after files, ideally in a binary file editor:

  • Do they have the same size?
  • Where do they differ, and how? Is there any pattern?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM