locked
Captured image to Byte array stored in a DB via Webservice

    Question

  • Hi

    Im creating a windows store app, and at a point in the app the user can capture a picture and upload it to a SQL DB, The picture among other inputs from the user is then converted into a PDF via a webservice.
    I’ve created a WebAPI MVC webservice, that return a custom object, then the user in the app make changes to the object and the post it to the service, the data is added to the SQL DB. Every things seems fine, but.. my pictures are in some point corrupted and can’t be generated whit the data from the SQL DB.
    SQL Table
    CREATE TABLE [dbo].[KontrolPumpesStation]
        (
              …    
              …
              Billede1 VARBINARY(MAX) ,
              Billede2 VARBINARY(MAX) ,
              Billede3 VARBINARY(MAX)
        );


    My Webservice model:
    public partial class KontrolPumpesStation
        {
        …
        …
    public byte[] Billede1 { get; set; }
                public byte[] Billede2 { get; set; }
                public byte[] Billede3 { get; set; }
        }

    Im my Windows store app I have a class like the one in the webservice but I have implemented INotifyPropertyChanged    
    Windows Store class:

    public class KontrolPumpesStation : INotifyPropertyChanged
        {
        …
        …
    private byte[] _billede1;
                private byte[] _billede2;
                private byte[] _billede3;

    public byte[] Billede1
            {
                get { return _billede1; }
                set { _billede1 = value; OnPropertyChanged(); }
            }

            public byte[] Billede2
            {
                get { return _billede2; }
                set { _billede2 = value; OnPropertyChanged(); }
            }

            public byte[] Billede3
            {
                get { return _billede3; }
                set { _billede3 = value; OnPropertyChanged(); }
            }
    }
    When the user captures a image im using this:

      async private void Billede1_OnClick(object sender, RoutedEventArgs e)
            {
                var picture = await CameraCapture();

                if (picture != null)
                {
                    Image image1 = (Image)FindChildControl<Image>(HubSectionImages, "ImageControl1");
                    image1.Source =  picture;
                    MainViewModel.KontrolPumpesStation.Billede1 = picture.ToByteArray();
                }
            }


       async private Task<WriteableBitmap> CameraCapture()
            {

                CameraCaptureUI cameraUI = new CameraCaptureUI();
                cameraUI.PhotoSettings.AllowCropping = true;
                cameraUI.PhotoSettings.MaxResolution = CameraCaptureUIMaxPhotoResolution.SmallVga;

                Windows.Storage.StorageFile capturedMedia =
                    await cameraUI.CaptureFileAsync(CameraCaptureUIMode.Photo);

                if (capturedMedia != null)
                {
                    using (var streamCamera = await capturedMedia.OpenAsync(FileAccessMode.Read))
                    {

                        BitmapImage bitmapCamera = new BitmapImage();
                        bitmapCamera.SetSource(streamCamera);

                        int width = bitmapCamera.PixelWidth;
                        int height = bitmapCamera.PixelHeight;

                        WriteableBitmap wBitmap = new WriteableBitmap(width, height);
                        using (var stream = await capturedMedia.OpenAsync(FileAccessMode.Read))
                        {
                            wBitmap.SetSource(stream);
                        }
                        return wBitmap;
                    }
                }
                return null;        }

    When i upload the object :

    public string CreateJsonFilePumpestationKontrol()
            {
                return JsonConvert.SerializeObject(KontrolPumpesStation);            
            }

       async public Task<bool> SavePumpestationKontrol(string jsonString)
            {
                _hasError = false;
                using (_client = new HttpClient())
                {
                    //Client settings
                    _client.BaseAddress = new Uri(WebServiceUrl);
                    _client.DefaultRequestHeaders.Accept.Clear();
                    _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));


                    //setting credentials
                    _client.DefaultRequestHeaders.Authorization =
                        new AuthenticationHeaderValue(
                            "Basic",
                            Convert.ToBase64String(Encoding.UTF8.GetBytes(
                                string.Format("{0}:{1}", "USER", "PASS"))));
                    
                    HttpContent content = new StringContent(jsonString);
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");             


                    var result = await _client.PostAsync("Webapi/api/KontrolPumpesStations", content);

                    if (result.IsSuccessStatusCode)
                    {
                        return true;
                    }
                    else
                    {
                        _hasError = true;
                        _errorMessage = result.Content.ToString();
                        return false;
                    }
                }
            }
    Every things seems to work and the object is added in the DB

    Billede1
    0x6F6C5D … (I’ve deleted the rest   )

    But every time I want to use the image I get an argument exception.

    Can anybody help me?

    Thanks

    /Jacob

    Sunday, November 2, 2014 11:24 AM

Answers

  • Hi again

    I found a solution, it was the code converting the captured image to byte[] that mate the bytes corrupt, this code did the work. :-)

     CameraCaptureUI cameraUI = new CameraCaptureUI();
    
                cameraUI.PhotoSettings.AllowCropping = false;
                cameraUI.PhotoSettings.MaxResolution = CameraCaptureUIMaxPhotoResolution.SmallVga;
    
                Windows.Storage.StorageFile capturedMedia =
                    await cameraUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
    
                if (capturedMedia != null)
                {
                    using (var streamCamera = await capturedMedia.OpenAsync(FileAccessMode.Read))
                    {
    
                        BitmapImage bitmapCamera = new BitmapImage();
                        bitmapCamera.SetSource(streamCamera);
                    
                        int width = bitmapCamera.PixelWidth;
                        int height = bitmapCamera.PixelHeight;
    
    
                        WriteableBitmap wBitmap = new WriteableBitmap(width, height);
    
                        using (var stream = await capturedMedia.OpenAsync(FileAccessMode.Read))
                        {
                            wBitmap.SetSource(stream);
    
                        }
    
                        Image image1 = (Image)FindChildControl<Image>(HubSectionImages, "ImageControl1");
                        image1.Source = wBitmap;
    
                    }
    
                    using (IRandomAccessStream stream = await capturedMedia.OpenReadAsync())
                    {
                        using (DataReader reader = new DataReader(stream.GetInputStreamAt(0)))
                        {
                            await reader.LoadAsync((uint)stream.Size);
                            byte[] pixeByte = new byte[stream.Size];
                            reader.ReadBytes(pixeByte);
                            MainViewModel.KontrolPumpesStation.Billede1 = pixeByte;
                        }
                    }
    
                }
    Thank's for your suggestions


    • Edited by Saugmann Friday, November 14, 2014 2:47 PM Edit in commments
    • Marked as answer by Saugmann Friday, November 14, 2014 2:47 PM
    Friday, November 14, 2014 2:46 PM

All replies

  • Hi Saugmann,

    But every time I want to use the image I get an argument exception.

    May I know in which line you get the argument exception? Let's see this code:

    async private void Billede1_OnClick(object sender, RoutedEventArgs e)
             {
                 var picture = await CameraCapture();
    
                 if (picture != null)
                 {
                     Image image1 = (Image)FindChildControl<Image>(HubSectionImages, "ImageControl1");
                     image1.Source =  picture;
                     MainViewModel.KontrolPumpesStation.Billede1 = picture.ToByteArray();
                 }
             }
    

    The Billede1 is set to CamearCapture but not a image, will you think its ok?

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Monday, November 3, 2014 5:16 AM
    Moderator
  • Hi James,

    Its when i want to use the image stored in the db.

    ex in this pdf i get error invalid parameter:

         if (vandvaerk.Billede1 != null)
                        {
                            using (MemoryStream ms = new MemoryStream(vandvaerk.Billede1))
                            {
                                var img = Bitmap.FromStream(ms);
                                var image = PdfBitmap.FromStream(ms);
                                g4.DrawImage(image, 40, boundY);
    
                                boundY += textLineSpacing;
                            }
                        }

    or in this asp.net MVCi get a blank image

    <div class="jumbotron">
        @{
        var base64 = Convert.ToBase64String(Model.Billede1);
        var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
    
        <img class="img-rounded" style="width: 90px;" src='@imgSrc' />
        }
    </div>

    Monday, November 3, 2014 6:26 AM
  • Thanks for more detail information. Let's narrow down the question because your current situation is too complex and hardly to locate the real problem.

    Here you have a CameraCapture() which return a WriteableBitmap, and later you assign the Billede1 as WritebleBitmap.ToByteArray() in the Billede1_OnClick method

    Billede1 = picture.ToByteArray();

    You convert the image directly to the ByteArray, but as I know we should not do like this, you may want to try:

    byte[] pixeBuffer = writeableBitmap.PixelBuffer.AsStream().ToArray();

    After that you could encode the image byte array and decode them.

    If you want to convert back the Byte array to image, you can try something below:

    using (var stream = new InMemoryRandomAccessStream())
    {
        await stream.WriteAsync(byteArray.AsBuffer());
        var image = new BitmapImage();
        stream.Seek(0);
        image.SetSource(stream);
    }
    
    

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.



    Wednesday, November 5, 2014 7:27 AM
    Moderator
  • Hi

    I tried as you suggested

    byte[] pixeBuffer = writeableBitmap.PixelBuffer.AsStream().ToArray();
    But i get an error in VS "Cannot resolve .ToArray"

    Then i tried this:            

       using (Stream stream = picture.PixelBuffer.AsStream())
                    {
                        MemoryStream memoryStream = new MemoryStream();
                        stream.CopyTo(memoryStream);
                        MainViewModel.KontrolVandvaerk.Billede1 = memoryStream.ToArray();
                    }

    But i still get an error when i try to use the bytearray as an image.

    Wednesday, November 5, 2014 12:08 PM
  • Can you convert back the image from byte by using the second code snippet I pasted in your app? for instance click a button to display the image converted back from byte array on a image control.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.


    Thursday, November 6, 2014 8:00 AM
    Moderator
  • Hi James

    Now i tried converting back but i don't get an image

        var picture = await CameraCapture();
    
                if (picture != null)
                {
    
    
                    Image image1 = (Image)FindChildControl<Image>(HubSectionImages, "ImageControl1");
                    image1.Source =  picture;
    
                    using (Stream stream = picture.PixelBuffer.AsStream())
                    {
                        MemoryStream memoryStream = new MemoryStream();
                        stream.CopyTo(memoryStream);
                        MainViewModel.KontrolPumpesStation.Billede1 = memoryStream.ToArray();
                    }
                    
    
                   
                    using (var stream = new InMemoryRandomAccessStream())
                    {
                        await stream.WriteAsync(MainViewModel.KontrolPumpesStation.Billede1.AsBuffer());
                        var image = new BitmapImage();
                        stream.Seek(0);
                        image.SetSource(stream);
    
                         Image image3 = (Image)FindChildControl<Image>(HubSectionImages, "ImageControl3");
                         image3.Source =  image;
                        
                    }
    
    
                }

    Friday, November 7, 2014 6:50 AM
  • Hi again

    I found a solution, it was the code converting the captured image to byte[] that mate the bytes corrupt, this code did the work. :-)

     CameraCaptureUI cameraUI = new CameraCaptureUI();
    
                cameraUI.PhotoSettings.AllowCropping = false;
                cameraUI.PhotoSettings.MaxResolution = CameraCaptureUIMaxPhotoResolution.SmallVga;
    
                Windows.Storage.StorageFile capturedMedia =
                    await cameraUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
    
                if (capturedMedia != null)
                {
                    using (var streamCamera = await capturedMedia.OpenAsync(FileAccessMode.Read))
                    {
    
                        BitmapImage bitmapCamera = new BitmapImage();
                        bitmapCamera.SetSource(streamCamera);
                    
                        int width = bitmapCamera.PixelWidth;
                        int height = bitmapCamera.PixelHeight;
    
    
                        WriteableBitmap wBitmap = new WriteableBitmap(width, height);
    
                        using (var stream = await capturedMedia.OpenAsync(FileAccessMode.Read))
                        {
                            wBitmap.SetSource(stream);
    
                        }
    
                        Image image1 = (Image)FindChildControl<Image>(HubSectionImages, "ImageControl1");
                        image1.Source = wBitmap;
    
                    }
    
                    using (IRandomAccessStream stream = await capturedMedia.OpenReadAsync())
                    {
                        using (DataReader reader = new DataReader(stream.GetInputStreamAt(0)))
                        {
                            await reader.LoadAsync((uint)stream.Size);
                            byte[] pixeByte = new byte[stream.Size];
                            reader.ReadBytes(pixeByte);
                            MainViewModel.KontrolPumpesStation.Billede1 = pixeByte;
                        }
                    }
    
                }
    Thank's for your suggestions


    • Edited by Saugmann Friday, November 14, 2014 2:47 PM Edit in commments
    • Marked as answer by Saugmann Friday, November 14, 2014 2:47 PM
    Friday, November 14, 2014 2:46 PM
  • Nice to see the solution :)

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Wednesday, November 26, 2014 9:34 AM
    Moderator