4

I have tried to bind the image from the column "Applicant's Image" in the datatable "Applicant's Details" in Data Set "data_set" through two methods. But When I run the Form Application I see no image displayed in the picturebox "imgusr". My binding source name is "bindSource".

Assuming the data_set retrieves everything correctly, what could be problem for image not being loaded into the picturebox "imgusr"??

Also, the picturebox property of sizeMode to "zoom".

    private void Update_Load(object sender, EventArgs e){
        data_set = blobj.srcforVU();
        bindSource.DataSource = data_set;
        bindSource.DataMember = "Applicant's Details";
        lbidvalue.DataBindings.Add(new Binding("Text", bindSource, "Applicant's ID", false));

        //method 1
        //Binding binding = new Binding("Image", bindSource, "Applicant's Image", true, DataSourceUpdateMode.OnPropertyChanged);
        //binding.Format += new ConvertEventHandler(binding_Format);
        //imgusr.DataBindings.Add(binding);
        //method 2
        imgusr.DataBindings.Add(new Binding("Image", bindSource, "Applicant's Image", true));

        tbfname.DataBindings.Add(new Binding("Text", bindSource, "First Name", true));
        tblname.DataBindings.Add(new Binding("Text", bindSource, "Last Name", true));
        tbgender.DataBindings.Add(new Binding("Text", bindSource, "Gender", true));
        tbbdate.DataBindings.Add(new Binding("Text", bindSource, "Birth Date", true));
        tbmob.DataBindings.Add(new Binding("Text", bindSource, "Mobile No", true));
        tbadd.DataBindings.Add(new Binding("Text", bindSource, "Address", true));
        tbcntry.DataBindings.Add(new Binding("Text", bindSource, "Country", true));
        tbmstat.DataBindings.Add(new Binding("Text", bindSource, "Is Married", true));
        tbspfname.DataBindings.Add(new Binding("Text", bindSource, "Spouse's First Name", true));
        tbsplname.DataBindings.Add(new Binding("Text", bindSource, "Spouse's Last Name", true));
        tbspage.DataBindings.Add(new Binding("Text", bindSource, "Spouse's Age", true));
        tbchild.DataBindings.Add(new Binding("Text", bindSource, "No Of Children", true));
        bindNavigator.BindingSource = bindSource;

        afterloadoptions();
    }

public void binding_Format(object sender, ConvertEventArgs e)
    {
        string path = (string)e.Value;
        e.Value = Image.FromFile(path);
    }
Sagar Maru
  • 65
  • 3
  • 10

1 Answers1

6

The solution can be as simple as this:

imgusr.DataBindings.Add(new Binding("Image", data_set, 
                                    "yourtablename.yourcolumnname", true));

Note that you need to tell the Binding to do the formatting by setting the last parameter (enableFormatting) to true. No more special code is needed to process the image.

Also note that I didn't try the necessary formatting to use blanks and apostrophes in the column name. I recommend using standard names!

And finally make sure to set the TableName property of the Table you want to use in your DataSet:

data_set.Tables[0].TableName = "yourtablename";

Update from your discussion it seems that you do not save the image data correctly to your dbms. Here is a version of your routine, that should work better:

byte[] img_byte = null;
long imgfilelength = 0;

private void StoreImage(string ChosenFile)
{
    try { 
        using (Image img = Image.FromFile(ChosenFile))
        using (MemoryStream ms = new MemoryStream())
        {
            img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            ms.Close();
            img_byte = ms.ToArray();
            imgfilelength = img_byte.Length;
        }
    } catch (Exception e) { MessageBox.Show(e.ToString()); }
}

Testing is as simple as that:

private void test_button_Click(object sender, EventArgs e)
{
    StoreImage(someImageFile);
    using (MemoryStream ms = new MemoryStream(img_byte))
    {
        aPictureBox.Image = Image.FromStream(ms);
    }
}

Do make sure to use the correct file format, e.g. Png or Jpeg etc..

TaW
  • 53,122
  • 8
  • 69
  • 111
  • rest everything is working fine except for image binding! – Sagar Maru Feb 17 '16 at 10:01
  • 1
    If have tested my code and it shows the 1st image in the table just fine. I use a blob column in mySql. Do you get an error? – TaW Feb 17 '16 at 10:12
  • by following your way, i neither got any error nor any images. By trying the smartis' method in his answer, I just got one written in the comment to that answer. Can u help me solve that? – Sagar Maru Feb 17 '16 at 10:15
  • 1
    Not using sql server, I'm afraid I can't. Did you notice Smartis' comment? This sounds as if at least testing with the new recommended datatype `varbinary(max)` might not just help but also be the better option anyway.. – TaW Feb 17 '16 at 10:18
  • So, what would be my 'max' then? – Sagar Maru Feb 17 '16 at 10:20
  • 1
    A parameter to set an upperlimit to the size so the dbms can do a better storage layout. Did you successfully pull out the image data in any other way? I somehow suspect they are faulty, esp. following the comments on the other answer.. Maybe you can show how you insert them? Do you know anything about the image format? – TaW Feb 17 '16 at 10:24
  • I wasn't able to retrieve image from any method which includes memory stream. I can successfully store image into database, but when i try to load back to picture box it shows parameter invalid error – Sagar Maru Feb 17 '16 at 10:27
  • Also, can byte array directly be inserted to varbinary or do i need to convert it to binary and then insert into database? – Sagar Maru Feb 17 '16 at 10:30
  • I would expect that writing it directly will work, or that you would get an error when you try. To create the byte array I use `MemoryStream ms = new MemoryStream(); pb_image.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); byte[] imageBytes = new byte[ms.Length]; ms.Position = 0; ms.Read(imageBytes, 0, imageBytes.Length);....CMD.Parameters.AddWithValue("@image", imageBytes);` – TaW Feb 17 '16 at 10:39
  • To do a simple test add a datagridview and set its datasource to your table. with its out-of-the-box defaults it sholuld create and fill all columns including the image. if it doesn't show those they are either flawed or have a weird format that need extra logic to decode. – TaW Feb 17 '16 at 10:42
  • Here it is my save code: private void StoreImage(string ChosenFile){ try { FileInfo fileImage = new FileInfo(ChosenFile); imgfilelength = fileImage.Length; FileStream fs = new FileStream(ChosenFile, FileMode.Open, FileAccess.Read, FileShare.Read); img_byte = new Byte[Convert.ToInt32(imgfilelength)]; fs.Close(); } catch(Exception e) { MessageBox.Show(e.ToString()); } } – Sagar Maru Feb 17 '16 at 10:44
  • I doubt that the code is correct as the fileinfo.length is not really the length of the resulting image bytes. try to use the code I gave you! – TaW Feb 17 '16 at 10:49
  • Yes, it doesn't show the images in the datagrid. Error: System.ArgumentException: Parameter is not valid. at System.Drawing.Image.FromStream(Stream stream, Boolean useEmbeddedColorManagement, Boolean validateImageData) at ....... – Sagar Maru Feb 17 '16 at 10:52
  • 2
    Just what I expected. The real length is what the memorystream reports, so you didn't store valid image data. once you correct that the original code you had ought to work.. fileinfo tells you only about the size on disk .. – TaW Feb 17 '16 at 10:53
  • Now, for your way, I got another error saying: System.NullReferenceException: Object reference not set to an instance of an object. – Sagar Maru Feb 17 '16 at 11:08
  • Actually I m uploading a image from a chosen file path. – Sagar Maru Feb 17 '16 at 11:09
  • hm, you will need to adapt the code to your situation, e.g. have a valid image and command etc.. loading the image from a path instead of using one in a picturebox will certainly work just fine, provided that path does point to a compatible image. (test by loading the image in a picturebox..) – TaW Feb 17 '16 at 11:12
  • Here, I just tried it out from here. #the storing method http://www.codeproject.com/Articles/10861/Storing-and-Retrieving-Images-from-SQL-Server-usin – Sagar Maru Feb 17 '16 at 11:14
  • Yeah, well, this seems, at least at first glance, to read not an image file, like jpeg or png but a binary file that contains the data as a byte array already. For real images you need to let somebody do the conversion to a bitmap.. – TaW Feb 17 '16 at 11:18
  • You may want to try the modified `StoreImage` method. I assumed you wanted to put the data into a class level variable? – TaW Feb 17 '16 at 11:26
  • Here it is my both of the functions: btnBrowse_Click(object sender, EventArgs e) { string ChosenFile = ""; openimgdiag.InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal); openimgdiag.Filter = "JPEG Images|*.jpg|GIF Images|*.gif|BITMAPS|*.bmp|PNG Images|*.png|PICT Images|*.pict or *.pct|TIFF Images|*.tiff or *.tif"; if (openimgdiag.ShowDialog() == DialogResult.Cancel) { MessageBox.Show("Operation Cancelled!!"); } else { ChosenFile = openimgdiag.FileName; appImg.Image = Image.FromFile(ChosenFile); } StoreImage(ChosenFile); } – Sagar Maru Feb 17 '16 at 11:30
  • and the store image was what I sent you before – Sagar Maru Feb 17 '16 at 11:30
  • You say if it isn't gonna work at all, then suggest modified one! – Sagar Maru Feb 17 '16 at 11:31
  • yeah, i want to put the data at class level byte array variable – Sagar Maru Feb 17 '16 at 11:32
  • check out the update! i couldn't try it, but it is pretty much a clone of the tested code form my comment.. – TaW Feb 17 '16 at 11:38
  • Yes, It is storing the image successfully... no errors! but when I retrieve it into datagrid, no image displayed. saying error: parameter invalid. – Sagar Maru Feb 17 '16 at 11:45
  • Hm, sure there are no more of the old invalid images out there? – TaW Feb 17 '16 at 11:46
  • nope! only one image I am storing into database! yes, the database isn't cleared, which contains old binary image values. but I tried to look up by just enterin another record in the table and retrieve in the datagrid. yet it is showing the same error – Sagar Maru Feb 17 '16 at 11:50
  • I now have tested the code and found it to fail indeed; see my much simpler update, which works here.. Good luck, i'll be afk for a day.. – TaW Feb 17 '16 at 12:09
  • Yeah, a typo, the SO editor doesn't pick up the whole name when double clicking a word like `img_byte`. The variable is not really needed anymore btw.. – TaW Feb 17 '16 at 12:15
  • working all fine!!! Thanks for the update. SO, it seems now I have a problem in loading images. Here's the way I m extracting images from the database! public byte[] LoadImagefromDB(long pid) { byte[] img = null; OpenConnState(M_conn); string str = "use db_Main \n select Person_Image from Main_Person where P_Id = " + pid; SqlCommand cmd = new SqlCommand(str, M_conn); try { img = (byte[])cmd.ExecuteScalar(); return img; } catch (System.Exception e) { MessageBox.Show(e.ToString()); return img; } finally { CloseConnState(myConn); } } – Sagar Maru Feb 17 '16 at 12:22
  • And here openConnState(conn) is just simple to open conn if closed and so is closeConnState(conn). And the query string is not a problem. So, can u find any prob? – Sagar Maru Feb 17 '16 at 12:24
  • specifically what to write in sql query to convert the binary data of image display the image in the datagrid – Sagar Maru Feb 17 '16 at 12:40
  • Also, can you help me out for the parameter invalid error while binding the image to the picture box which is my actual question! – Sagar Maru Feb 18 '16 at 05:09
  • When I use your method it works perfectly, because I have the same bytes[] which I stored into the database. But in my load function, when I retrieve bytes[] from the database as shown in the method LoadImagefromDB() above in my comments, it always show that parameter is invalid. And so, the main problem here is in load method. – Sagar Maru Feb 18 '16 at 05:36