0

Here is the situation:

  1. I could Save() an Employee entry with a picture from PixPictureBox to the database.
  2. If I edit the employee entry and change the picture from the PixPictureBox with a new one, the Update() goes fine.
  3. This is where the error goes, whenever I edit an Employee entry and don't change the PixPictureBox's image, the Update() method throws the following exception:

$exception {"A generic error occurred in GDI+."} System.Runtime.InteropServices.ExternalException

This error is firing from this method:

private byte[] ImageToByteArray(Image imageIn)
{
    using (var ms = new MemoryStream())
    {
        imageIn.Save(ms, imageIn.RawFormat);
        return ms.ToArray();
    }
}

This is my GetParams() method where ImageToByteArray is being used:

private void GetParams()
{
    Ebm.ResetParams();
    Ebm.Params.Id = IdTextBox.Text.GetInt();
    Ebm.Params.EmployeeCode = Ebm.GenerateEmployeeCode();
    Ebm.Params.LastName = LastNameTextBox.Text;
    Ebm.Params.FirstName = FirstNameTextBox.Text;
    Ebm.Params.MiddleName = MiddleNameTextBox.Text;
    Ebm.Params.GenderId = GenderBox.SelectedValue.GetInt();
    Ebm.Params.BirthDate = BirthDatePicker.Value.GetDateTime();
    Ebm.Params.Age = AgeTextBox.Text.GetInt();
    Ebm.Params.Salary = SalaryTextBox.Text.GetDecimal();
    Ebm.Params.StatId = 1;

    if (PixPictureBox.Image != null)
    {
        Ebm.Params.Pics = ImageToByteArray(PixPictureBox.Image);
    }              
}

Here is the method I use to load the picture from the database to PixPictureBox

private Image ByteArrayToImage(byte[] bytesArr)
{
   using (var memstr = new MemoryStream(bytesArr))
   {
          Image img = Image.FromStream(memstr);
          return img;
   }
}

This is how I load it:

private void LoadDetails()
{
    IdTextBox.Text = Ebm.Item.Id.GetString();
    EmployeeCodeTextBox.Text = Ebm.Item.EmployeeCode;
    LastNameTextBox.Text = Ebm.Item.LastName;
    FirstNameTextBox.Text = Ebm.Item.FirstName;
    MiddleNameTextBox.Text = Ebm.Item.MiddleName;
    GenderBox.SelectedValue = Ebm.Item.GenderId;
    BirthDatePicker.Value = Ebm.Item.BirthDate;
    AgeTextBox.Text = Ebm.Item.Age.GetString();
    SalaryTextBox.Text = Ebm.Item.Salary.GetString();

    try
    {
        PixPictureBox.Image = ByteArrayToImage(Ebm.Item.Pics);
    }
    catch (Exception ex)
    {
        PixPictureBox.Image = null;
    }

}

I also get this error from my MemoryStream which I think is related to the exception:

enter image description here

Pamingkas Sevada
  • 432
  • 9
  • 21
  • didnt change the picture, meaning, i loaded the picture from the db, so i just leave it as it is then click save, the error occurs on that imagetobytearray(). if i am trying to update an entry and change the picture (via open dialog box), the update goes fine. but if i just leave the picture (loaded from the db) as it is and didnt use another picture(via opendialog box), the imagetobytearrays throws exception – Pamingkas Sevada Aug 30 '18 at 08:17
  • Then there's something wrong with the code where you get the image from the database and place it in the PictureBox control, we need to see that code. – 41686d6564 stands w. Palestine Aug 30 '18 at 08:19
  • i updated the post – Pamingkas Sevada Aug 30 '18 at 08:23
  • The problem as I suspected is that you're disposing the MemoryStream [while you shouldn't](https://stackoverflow.com/a/336396/4934172). You must keep the stream open for the lifetime of the Bitmap and you should only dispose the bitmap itself after you're done with it. – 41686d6564 stands w. Palestine Aug 30 '18 at 08:28
  • Possible duplicate of [Image.Save(..) throws a GDI+ exception because the memory stream is closed](https://stackoverflow.com/questions/336387/image-save-throws-a-gdi-exception-because-the-memory-stream-is-closed) – 41686d6564 stands w. Palestine Aug 30 '18 at 08:29
  • i already tried using this var xs = new MemoryStream(); imageIn.Save(xs, imageIn.RawFormat); return xs.ToArray(); but the same error occurs – Pamingkas Sevada Aug 30 '18 at 08:30
  • 1
    Are you sure you didn't dispose the MemoryStream somewhere in your code? If so, please provide a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – 41686d6564 stands w. Palestine Aug 30 '18 at 08:33
  • apparently i did. it is in ByteArrayToImage() – Pamingkas Sevada Aug 30 '18 at 08:35
  • 1
    When you assign the Image, in `private Image ByteArrayToImage(byte[] bytesArr)`, Enclose the `Image img = Image.FromStream(memstr);` in an `using` block. Then return a clone of the Image: `return img.Clone() as Image;` or `return (Image)img.Clone();` – Jimi Aug 30 '18 at 08:36
  • @PamingkasSevada I already told you what's wrong with your _current_ `ByteArrayToImage` method. If you have changed that and still have the same problem, please read what an [MCVE](https://stackoverflow.com/help/mcve) is, and provide one. – 41686d6564 stands w. Palestine Aug 30 '18 at 08:39

1 Answers1

0

I just needed to change the ByteArrayToImage() method into this:

private Image ByteArrayToImage(byte[] bytesArr)
{
    var mem = new MemoryStream(bytesArr);
    Image img = Image.FromStream(mem);
    return img;
}
Pamingkas Sevada
  • 432
  • 9
  • 21