0

First of all,I'm sorry for my poor English.

I work on this project for few days without any solution for my problem. I try to send a picture from my UWP application to a Webservice in c#. I did this thing in a android app without any problem.

I should encode a image into a base64 string that the webservice can decode it.

I have two issues , the first is that if I try ( with a online decoder) to decode my base64 string, this gave me something like this with this code.

In the image, we can see the it have not show the whole picture.:

I write it with this code to base64:

private async void ToBase64(WriteableBitmap img)
{
    var encoded = new InMemoryRandomAccessStream();

    // Copy buffer to pixels
    byte[] pixels;
    using (var stream = img.PixelBuffer.AsStream())
    {
        pixels = new byte[(uint)stream.Length];
        await stream.ReadAsync(pixels, 0, pixels.Length);
    }

    var encoder = await BitmapEncoder
        .CreateAsync(BitmapEncoder.PngEncoderId, encoded);
    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
        BitmapAlphaMode.Premultiplied, (uint)img.PixelWidth, (uint)img.PixelHeight
        , 96, 96, pixels);
    await encoder.FlushAsync();
    encoded.Seek(0);

    var array = new byte[encoded.Size];
    await encoded.AsStream().ReadAsync(array, 0, array.Length);

    Base64String = Convert.ToBase64String(array);
}

My second issue is that if I try to send this Base64 to my webservices and decode it with FromBase64String, the webservice return an error "The base64 string format is not correct". I don't understand it because as we can see, online decoder can decode it and i don't have this issue with android app.

If you have any ideas about this issues. I tried multiple things that i saw on internet

Thank you per advance.

EDIT 1

This is my decode method. This method work with Bitmap base64 send with android app.

[WebMethod]
     public string uploadPhoto(string image)
        {
            byte[] bytes = Convert.FromBase64String(image);

            using (var imageFile = new FileStream("directory+filename", FileMode.Create))
            {
                imageFile.Write(bytes, 0, bytes.Length);
                imageFile.Flush();
            }     

            return number;
        }

EDIT 2

It works with this code :

public async Task<String> SaveToBytesAsync(ImageSource imageSource)
        {
            byte[] imageBuffer;
            var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
            var file = await localFolder.CreateFileAsync("temp.jpg", CreationCollisionOption.ReplaceExisting);
            using (var ras = await file.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None))
            {
                WriteableBitmap bitmap = imageSource as WriteableBitmap;
                var stream = bitmap.PixelBuffer.AsStream();
                byte[] buffer = new byte[stream.Length];
                await stream.ReadAsync(buffer, 0, buffer.Length);
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, ras);
                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96.0, 96.0, buffer);
                await encoder.FlushAsync();

                var imageStream = ras.AsStream();
                imageStream.Seek(0, SeekOrigin.Begin);
                imageBuffer = new byte[imageStream.Length];
                var re = await imageStream.ReadAsync(imageBuffer, 0, imageBuffer.Length);
            }
            await file.DeleteAsync(StorageDeleteOption.Default);
            return Convert.ToBase64String(imageBuffer);
        }

the decoding on the server give a full image. Thanks.

Omri Btian
  • 6,499
  • 4
  • 39
  • 65

2 Answers2

0

is there a reason to encode the image?, try this.

    string base64String = await ToBase64Async(bitmap);

    public async Task<string> ToBase64Async(WriteableBitmap bitmap)
    {
        using (Stream stream = bitmap.PixelBuffer.AsStream())
        {
            stream.Position = 0; 
            var reader = new DataReader(stream.AsInputStream());
            var bytes = new byte[stream.Length];
            await reader.LoadAsync((uint)stream.Length);
            reader.ReadBytes(bytes);
            return Convert.ToBase64String(bytes);
        }

    }
Stamos
  • 3,938
  • 1
  • 22
  • 48
  • Thanks for the answer, but i have already tried this solution, it gave me something like this "CxMS/wsTEv8NEhH/DRIR/xEREf8RERH/FRAR/xQPEP8UDxD/FA8Q/xQPEP8UDxD/EhAQ/xIQEP8QEBD/EBAQ/xAQEP8QEBD/EBAQ/xAQEP8QEBD/EBAQ/xAQEP8QEBD/EBAQ/" but i can't decode it with a online decoder or with Convert.FromBase64String on the server side. I don't know what to do :/ – benoit rastier May 18 '16 at 07:07
  • Ok i have news. The error encountered when i tried to send this string is because the string is too large. I resize the picture and everything il alright during the sending. Now the problem is that i have a corrupted file when i decode it on the server side and save it. – benoit rastier May 18 '16 at 08:15
  • @benoitrastier delete it and edit your question please. – Stamos May 18 '16 at 09:34
0

Try use the code to base64

private async Task<string> ToBase64(Image control)
{
    var bitmap = new RenderTargetBitmap();
    await bitmap.RenderAsync(control);
    return await ToBase64(bitmap);
}

And if you have a WriteableBitmap ,try use the code:

private async Task<string> ToBase64(WriteableBitmap bitmap)
{
    var bytes = bitmap.PixelBuffer.ToArray();
    return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
}

If your image is a SotrageFile,you can use

private async Task<string> ToBase64(StorageFile bitmap)
{
    var stream = await bitmap.OpenAsync(Windows.Storage.FileAccessMode.Read);
    var decoder = await BitmapDecoder.CreateAsync(stream);
    var pixels = await decoder.GetPixelDataAsync();
    var bytes = pixels.DetachPixelData();
    return await ToBase64(bytes, (uint)decoder.PixelWidth, (uint)decoder.PixelHeight, decoder.DpiX, decoder.DpiY);
}

If your picture is RenderTargetBitmap

private async Task<string> ToBase64(RenderTargetBitmap bitmap)
{
    var bytes = (await bitmap.GetPixelsAsync()).ToArray();
    return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
}

See https://codepaste.net/ijx28i

http://lindexi.oschina.io/lindexi/post/win10-uwp-%E8%AF%BB%E5%8F%96%E4%BF%9D%E5%AD%98WriteableBitmap-BitmapImage/

lindexi
  • 4,182
  • 3
  • 19
  • 65