Resolved Display picture from SQLite to pictureBox

Kostakis45

Active member
Joined
Apr 3, 2022
Messages
34
Programming Experience
Beginner
Hello everyone.I'm new here so please show some mercy on me.
In my program I store some data to SQLite database in which some data are pictures which in SQLite db are stored as System.Drawing.Bitmap
Picture 1
Now my main problem is that i cannot or know how to load these pictures back to pictureBox's.Bellow is my code so far.Any help and suggestions?

Database Path:
 string path ="Injection_Settings.db";
        string connection = @"URI=file:"+Application.StartupPath+"\\Injection_Settings.db";

Database Creation:
 private void Create_Database()
        {
            if(!System.IO.File.Exists(path))
            {
                SQLiteConnection.CreateFile(path);
                using (var sqlite = new SQLiteConnection(@"Data Source = " + path))
                {
                    sqlite.Open();
                    string dn_table = "CREATE TABLE IF NOT EXISTS Description(Mould_Code INTEGER NOT NULL PRIMARY KEY,Machine_Number INTEGER NOT NULL,Machine_Type TEXT NOT NULL,Supplier TEXT,Colour TEXT NOT NULL,Plastic_Type_1 TEXT,Plastic_Type_2 TEXT,Plastic_Type_3 TEXT,Plastic_Type_1_Val INTEGER,Plastic_Type_2_Val INTEGER,Plastic_Type_3_Val INTEGER,Date_Time TEXT NOT NULL, Item_Name TEXT NOT NULL,Image_1 BLOB,Image_2 BLOB)";
                    SQLiteCommand command = new SQLiteCommand(dn_table,sqlite);
                    command.ExecuteNonQuery();
                }
            }
            else
            {
                if(System.IO.File.Exists(path))
                {
                    using (var sqlite = new SQLiteConnection(@"Data Source = " + path))
                    {
                        sqlite.Open();
                        string dn_table = "SELECT * FROM Description";
                        SQLiteCommand command = new SQLiteCommand(dn_table, sqlite);
                        command.ExecuteNonQuery();

                        if(dn_table == null)
                        {
                            MessageBox.Show("Αδυναμία δημιουργίας βάσης δεδομένων");
                        }
                    }                
                }            
                return;
            }
        }
Data Insertion:
private void AddToDatatable_Click(object sender, EventArgs e)
        {
            var con = new SQLiteConnection(connection);
            con.Open();
            var cmd = new SQLiteCommand(con);

            cmd.CommandText = "INSERT INTO Description (Mould_Code,Machine_Number,Machine_Type,Supplier,Colour,Plastic_Type_1,Plastic_Type_2,Plastic_Type_3,Plastic_Type_1_Val,Plastic_Type_2_Val,Plastic_Type_3_Val,Date_Time,Item_Name,Image_1,Image_2) VALUES (@Mould_Code,@Machine_Number,@Machine_Type,@Supplier,@Colour,@Plastic_Type_1,@Plastic_Type_2,@Plastic_Type_3,@Plastic_Type_1_Val,@Plastic_Type_2_Val,@Plastic_Type_3_Val,@Date_Time,@Item_Name,@Image_1,@Image_2)";

            string Mould_Code = mould_code_input.Text;
            string Machine_Number = machine_number_input.Text;
            string Machine_Type = machine_type_input.Text;
            string Supplier = supplier_input.Text;
            string Colour = colour_input.Text;
            string Plastic_Type_1 = comboBox1.Text;
            string Plastic_Type_2 = comboBox2.Text;
            string Plastic_Type_3 = comboBox3.Text;
            string Plastic_Type_1_Val = numericUpDown1.Text;
            string Plastic_Type_2_Val = numericUpDown2.Text;
            string Plastic_Type_3_Val = numericUpDown3.Text;
            string Date_Time = dateTimePicker1.Text;
            string Item_Name = item_name_input.Text;
            Image Image_1 = pictureBox3.Image;
            Image Image_2 = pictureBox4.Image;

            if (mould_code_input == null
               || machine_number_input == null
               || machine_type_input.Text == null
               || colour_input.Text == null
               || dateTimePicker1.Text == null
               || item_name_input.Text == null)            
            {
                MessageBox.Show("Τα πεδία με * δεν μπορούν να είναι κενά.");            
            }

            cmd.Parameters.AddWithValue("@Mould_Code", Mould_Code);
            cmd.Parameters.AddWithValue("@Machine_Number", Machine_Number);
            cmd.Parameters.AddWithValue("@Machine_Type", Machine_Type);
            cmd.Parameters.AddWithValue("@Supplier", Supplier);
            cmd.Parameters.AddWithValue("@Colour", Colour);        
            cmd.Parameters.AddWithValue("@Plastic_Type_1", Plastic_Type_1);
            cmd.Parameters.AddWithValue("@Plastic_Type_2", Plastic_Type_2);
            cmd.Parameters.AddWithValue("@Plastic_Type_3", Plastic_Type_3);
            cmd.Parameters.AddWithValue("@Plastic_Type_1_Val", Plastic_Type_1_Val);
            cmd.Parameters.AddWithValue("@Plastic_Type_2_Val", Plastic_Type_2_Val);
            cmd.Parameters.AddWithValue("@Plastic_Type_3_Val", Plastic_Type_3_Val);
            cmd.Parameters.AddWithValue("@Date_Time", Date_Time);
            cmd.Parameters.AddWithValue("@Item_Name", Item_Name);
            cmd.Parameters.AddWithValue("@Image_1", Image_1);
            cmd.Parameters.AddWithValue("@Image_2", Image_2);
            cmd.ExecuteNonQuery();
         
            MessageBox.Show("Επιτυχής καταχώρηση στοιχείων");
            con.Close();
        }
Searching and display data when press OK button:
 private void Search_Ok_Click(object sender, EventArgs e)
        {
            tabControl2.Visible = true;
            tabControl1.Visible = false;

            string search_values = Search_Box.Text; // Τιμή απο το Search_Box

            var con = new SQLiteConnection(connection);
            con.Open();
            var cmd = new SQLiteCommand(con);        
            cmd.CommandText = "SELECT * FROM Description WHERE Mould_Code = '" + search_values + "'";        
            SQLiteDataReader reader = cmd.ExecuteReader();
            reader.Read();

            //Περιγραφή
            mould_lbl.Text = reader["Mould_Code"].ToString();
            machine_number_lbl.Text = reader["Machine_Number"].ToString();
            machine_lbl.Text = reader["Machine_Type"].ToString();
            supplier_lbl.Text = reader["Supplier"].ToString();
            colour_lbl.Text = reader["Colour"].ToString();
            plastic1_lbl.Text = reader["Plastic_Type_1"].ToString();
            plastic2_lbl.Text = reader["Plastic_Type_2"].ToString();
            plastic3_lbl.Text = reader["Plastic_Type_3"].ToString();
            plastic_val_1_lbl.Text = reader["Plastic_Type_1_Val"].ToString();
            plastic_val_2_lbl.Text = reader["Plastic_Type_2_Val"].ToString();
            plastic_val_3_lbl.Text = reader["Plastic_Type_3_Val"].ToString();
            date_time_lbl.Text = reader["Date_Time"].ToString();
            item_name_lbl.Text = reader["Item_Name"].ToString();
            pictureBox1.Image = (Bitmap)(new ImageConverter()).ConvertFrom);//Trying to make it work
            //pictureBox2.Image = reader["Image_2"].ToString;

            //Εκχυση

            con.Close();
        }
Searching and display data when press ENTER key:
 private void Search_Box_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                tabControl2.Visible = true;
                tabControl1.Visible = false;

                string search_values = Search_Box.Text; // Τιμή απο το Search_Box

                var con = new SQLiteConnection(connection);
                con.Open();
                var cmd = new SQLiteCommand(con);
                cmd.CommandText = "SELECT * FROM Description WHERE Mould_Code = '" + search_values + "'";
                SQLiteDataReader reader = cmd.ExecuteReader();
                reader.Read();            

                //Περιγραφή
                mould_lbl.Text = reader["Mould_Code"].ToString();
                machine_number_lbl.Text = reader["Machine_Number"].ToString();
                machine_lbl.Text = reader["Machine_Type"].ToString();
                supplier_lbl.Text = reader["Supplier"].ToString();
                colour_lbl.Text = reader["Colour"].ToString();
                plastic1_lbl.Text = reader["Plastic_Type_1"].ToString();
                plastic2_lbl.Text = reader["Plastic_Type_2"].ToString();
                plastic3_lbl.Text = reader["Plastic_Type_3"].ToString();
                plastic_val_1_lbl.Text = reader["Plastic_Type_1_Val"].ToString();
                plastic_val_2_lbl.Text = reader["Plastic_Type_2_Val"].ToString();
                plastic_val_3_lbl.Text = reader["Plastic_Type_3_Val"].ToString();
                date_time_lbl.Text = reader["Date_Time"].ToString();
                item_name_lbl.Text = reader["Item_Name"].ToString();

                //Εκχυση
            }
        }

After reading all the day all kind of Documantations and searching all the web for a solution I found this code:

Convert to Base64 and reverse:
public string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // Convert Image to byte[]
                image.Save(ms, format);
                byte[] imageBytes = ms.ToArray();

                // Convert byte[] to Base64 String
                string base64String = Convert.ToBase64String(imageBytes);
                return base64String;
            }
        }

        public Image Base64ToImage(string base64String)
        {
            // Convert Base64 String to byte[]
            byte[] imageBytes = Convert.FromBase64String(base64String);
            MemoryStream ms = new MemoryStream(imageBytes, 0,
              imageBytes.Length);

            // Convert byte[] to Image
            ms.Write(imageBytes, 0, imageBytes.Length);
            Image image = Image.FromStream(ms, true);
            return image;
        }

But i dunno how to implement it to my needs,because I don't see how to add the image to be converted or how to take the converted image and display it again in another pictureBox.
 
Last edited:

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,466
Location
Sydney, Australia
Programming Experience
10+
With most databases, you don't save Image objects but rather save the Image as a byte array and save that. You then retrieve that byte array and create a new Image object from it. I would expect SQLite to work the same way, but maybe I'm wrong. If you use the debugger to actually look at that field, i.e. reader["Image_1"], what does it tell you it is? It should be obvious that this wouldn't work:
C#:
pictureBox2.Image = reader["Image_2"].ToString;
Why would you think that loading a string into a PictureBox, where an Image is expected, would be a good thing? If you really do get an Image object back then you simply cast it as that type and assign it:
C#:
pictureBox2.Image = (Image) reader["Image_2"];
 

Kostakis45

Active member
Joined
Apr 3, 2022
Messages
34
Programming Experience
Beginner
With most databases, you don't save Image objects but rather save the Image as a byte array and save that. You then retrieve that byte array and create a new Image object from it. I would expect SQLite to work the same way, but maybe I'm wrong. If you use the debugger to actually look at that field, i.e. reader["Image_1"], what does it tell you it is? It should be obvious that this wouldn't work:
C#:
pictureBox2.Image = reader["Image_2"].ToString;
Why would you think that loading a string into a PictureBox, where an Image is expected, would be a good thing? If you really do get an Image object back then you simply cast it as that type and assign it:
C#:
pictureBox2.Image = (Image) reader["Image_2"];
I tried (Image) reader["Image_2"] too without luck.
Also i saw many posts about what you said but i find it hard to implement in my existing code without changing it completely.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
5,251
Location
Chesapeake, VA
Programming Experience
10+
Show us your attempts and the errors that you are getting.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
5,251
Location
Chesapeake, VA
Programming Experience
10+
When you save an image into a blob, you need to pull the bytes out of an image instance and store the bytes into a byte array and then that byte array into the blob. Conversely, when you load an image from a blob, you need to get the byte array from the blob, then load the bytes back into an image instance.


 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,466
Location
Sydney, Australia
Programming Experience
10+
I would recommend against storing the image data as base-64 text. Just save the binary data. Converting between an Image object and a byte array or back is quite simple:
C#:
private byte[] ConvertImageToBytes(Image image)
{
    using (var stream = new MemoryStream())
    {
        image.Save(stream, image.RawFormat);

        return stream.ToArray();
    }
}

private Image ConvertBytesToImage(byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
        stream.Position = 0L;

        return Image.FromStream(stream);
    }
}
 

Kostakis45

Active member
Joined
Apr 3, 2022
Messages
34
Programming Experience
Beginner
Thanks for replying and helping me.Once I'm done from work I'll try to implement the converter again. Yesterday i couldn't because I didn't know how to handle the parameters.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
5,251
Location
Chesapeake, VA
Programming Experience
10+
Whenever possible, choose to be strongly-typed rather than stringly typed. Choose the data type that is the closest match to the data you are storing. In the case of images, use blobs instead of base64 encoded text. I also noticed in your original post that you were storing date/time in string. You should use the native date time SQL type instead of text.
 

Kostakis45

Active member
Joined
Apr 3, 2022
Messages
34
Programming Experience
Beginner
I would recommend against storing the image data as base-64 text. Just save the binary data. Converting between an Image object and a byte array or back is quite simple:
C#:
private byte[] ConvertImageToBytes(Image image)
{
    using (var stream = new MemoryStream())
    {
        image.Save(stream, image.RawFormat);

        return stream.ToArray();
    }
}

private Image ConvertBytesToImage(byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
        stream.Position = 0L;

        return Image.FromStream(stream);
    }
}
See the picture above
What am I doing wrong?
It says cannot implicitly convert type Byte[] to System.Drawing.Image
And if I do it like that and that. <-------Images in (that) words.
It throws a null Exception see ----> here.
 
Last edited:

Kostakis45

Active member
Joined
Apr 3, 2022
Messages
34
Programming Experience
Beginner
Whenever possible, choose to be strongly-typed rather than stringly typed. Choose the data type that is the closest match to the data you are storing. In the case of images, use blobs instead of base64 encoded text. I also noticed in your original post that you were storing date/time in string. You should use the native date time SQL type instead of text.
Check this. That's why i chose to save it as string. My DB is SQLite.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
5,251
Location
Chesapeake, VA
Programming Experience
10+
ConvertImageToBytes() returns a byte array. You can't put that byte array straight into an image like you are doing here:
C#:
Image Image_1 = ConvertImageToBytes(pictureBox3.Image);
You want something like:
C#:
byte [] image1data = ConvertImageToBytes(pictureBox3.Image);

It is this image1data which you want to store into the blob.

As for your null exception, that will happen if you pass in a null object. Why would you expect anything different?
 

Kostakis45

Active member
Joined
Apr 3, 2022
Messages
34
Programming Experience
Beginner
ConvertImageToBytes() returns a byte array. You can't put that byte array straight into an image like you are doing here:
C#:
Image Image_1 = ConvertImageToBytes(pictureBox3.Image);
You want something like:
C#:
byte [] image1data = ConvertImageToBytes(pictureBox3.Image);

It is this image1data which you want to store into the blob.

As for your null exception, that will happen if you pass in a null object. Why would you expect anything different?
It's the same. See here.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
5,251
Location
Chesapeake, VA
Programming Experience
10+
Then that means that pictureBox3.Image is null.
 

Kostakis45

Active member
Joined
Apr 3, 2022
Messages
34
Programming Experience
Beginner
Then that means that pictureBox3.Image is null.
I don't think that's the case. Because before implementation of converters when ia insert an image to pictureBox and add it to db it saves it as System.Drawing.Image. I'm constantly checking that through SQLite DB Browser.

I found the problem.
The pictures that I was trying to save was copied from Word.That's why it didn't save them and throws nullException.
I tried to save normal png's and it saved them successfully as BLOB this time into the db.
Now i need to figure out how to make the images from Word files to be saved to.
Do you know if images from Word have saperate extension?
 
Last edited:

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
5,251
Location
Chesapeake, VA
Programming Experience
10+
The proof is in the pudding. Look at your callstack. Whomever is calling ConvertImageToBytes() is passing in a null value as the parameter.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
5,251
Location
Chesapeake, VA
Programming Experience
10+
Also, please stop posting code in screenshots. Please post code as text in code tags. Also post the exception details as text also in code tags, or as quotes.
 

Kostakis45

Active member
Joined
Apr 3, 2022
Messages
34
Programming Experience
Beginner
So.After some modifications I implented both converters.
For displaying the images back i did this:
Searching and display data when press ENTER key:
            byte[] Image_1 = (byte[]) reader["Image_1"];
            pictureBox1.Image = ConvertBytesToImage(Image_1);
            byte[] Image_2 = (byte[])reader["Image_2"];
            pictureBox2.Image = ConvertBytesToImage(Image_2);

Thanks for all the help you provided.
 
Top Bottom