16

我正在尝试使用带有 CF 的 WinForm 上的应用程序使用 SQLite 保存和加载图像。我找到了一种将图像保存到数据库中的方法,但我不知道它是否正确,因为我找不到加载存储在数据库中的图像的方法。

我有一个将图像转换为 Base64 的代码:

public void 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);
            SaveImage(base64String);
        }
    }

这是我将图像保存到数据库中的代码:

void SaveImage(string pic){
        string query = "insert into Table (Photo) values (@pic);"; 
        string conString = @" Data Source = \Program Files\Users.s3db ";            
        SQLiteConnection con = new SQLiteConnection(conString); 
        SQLiteCommand cmd = new SQLiteCommand(query, con);
        cmd.Parameters.Add("@pic",DbType.String);
        con.Open(); 
        try{
            cmd.ExecuteNonQuery();
        }
        catch (Exception exc1){
            MessageBox.Show(exc1.Message);
        }
        con.Close();
    }

我有一个与 ImageToBase64 相反的代码,但首先我需要从数据库加载图像。有什么想法吗?

编辑我正在尝试按照查理的建议使用 blob 来保存图像。我试过这段代码:

Image photo = new Bitmap(@"\Photos\Image20120601_1.jpeg");
SaveImage(photo);

void SaveImage(Image pic){
string conString = @" Data Source = \Program Files\Users.s3db ";            
SQLiteConnection con = new SQLiteConnection(conString);
SQLiteCommand cmd = con.CreateCommand();
cmd.CommandText = String.Format("INSERT INTO Table (Photo) VALUES (@0);");
SQLiteParameter param = new SQLiteParameter("@0", System.Data.DbType.Binary);
param.Value = pic;
cmd.Parameters.Add(param);
con.Open(); 
try{
    cmd.ExecuteNonQuery();
}
catch (Exception exc1){
    MessageBox.Show(exc1.Message);
}
con.Close();}

但是当我ExcecuteNonQuery()它捕获InvalidCastException错误。

有什么建议吗?

解决方案此代码将图像保存到数据库中,然后加载图像以将其显示在图片框中:

namespace ImagenSQLite
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Image photo = new Bitmap(@"\Photos\Image20120601_1.jpeg");
            byte[] pic = ImageToByte(photo, System.Drawing.Imaging.ImageFormat.Jpeg);
            SaveImage(pic);
            LoadImage();
        }

        public byte[] ImageToByte(Image image, System.Drawing.Imaging.ImageFormat format){
            using (MemoryStream ms = new MemoryStream())
            {
                // Convert Image to byte[]
                image.Save(ms, format);
                byte[] imageBytes = ms.ToArray();
                return imageBytes;
            }
        }
        //public Image Base64ToImage(string base64String)
         public Image ByteToImage(byte[] imageBytes)
        {
            // Convert byte[] to Image
            MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
            ms.Write(imageBytes, 0, imageBytes.Length);
            Image image = new Bitmap(ms);
            return image;
        }
        /***************** SQLite **************************/
        void SaveImage(byte[] imagen){
            string conStringDatosUsuarios = @" Data Source = \Program Files\GPS___CAM\Data\DatosUsuarios.s3db ";            
            SQLiteConnection con = new SQLiteConnection(conStringDatosUsuarios); 
            SQLiteCommand cmd = con.CreateCommand();
            cmd.CommandText = String.Format("INSERT INTO Empleados (Foto) VALUES (@0);");
            SQLiteParameter param = new SQLiteParameter("@0", System.Data.DbType.Binary);
            param.Value = imagen;
            cmd.Parameters.Add(param);
            con.Open();

            try
            {
                cmd.ExecuteNonQuery();
            }
            catch (Exception exc1)
            {
                MessageBox.Show(exc1.Message);
            }
            con.Close();
        }
        void LoadImage(){
            string query = "SELECT Photo FROM Table WHERE ID='5';";
            string conString = @" Data Source = \Program Files\Users.s3db ";
            SQLiteConnection con = new SQLiteConnection(conString); 
            SQLiteCommand cmd = new SQLiteCommand(query, con);            
            con.Open();
            try
            {
                IDataReader rdr = cmd.ExecuteReader();
                try
                {
                    while (rdr.Read())
                    {
                        byte[] a = (System.Byte[])rdr[0];
                        pictureBox1.Image = ByteToImage(a);
                    }
                }
                catch (Exception exc) { MessageBox.Show(exc.Message); }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
            con.Close();
        }       
    }
}

谢谢你的帮助!

4

2 回答 2

8

要从数据库加载图像,您可以使用 SQLselect语句来取回数据,就像您处理任何其他类型的数据一样。base64 编码的图像以字符串形式存储在 SQLite 数据库中。因此,您将其作为字符串检索,就像您在数据库中存储任何其他字符串(例如,您的姓名)一样。

string LoadImage() {
    string query = "select Photo from Table;"; 
    string conString = @" Data Source = \Program Files\Users.s3db ";            
    SQLiteConnection con = new SQLiteConnection(conString); 
    SQLiteCommand cmd = new SQLiteCommand(query, con);
    string base64EncodedImage = null;
    con.Open(); 
    try {
        IDataReader reader = cmd.ExecuteReader();
        reader.Read(); // advance the data reader to the first row
        base64EncodedImage = (string) reader["Photo"];
        reader.Close();
    }
    catch (Exception ex) {
        MessageBox.Show(ex.Message);
    }
    con.Close();
    return base64EncodedImage;
}

与您的保存代码一样,我加载图像的示例代码仅使用一张保存到表中的图像。要加载和保存多个图像,您需要在表中插入一个 ID 字段,然后where在 SQLselect语句中使用子句。


我不确定我个人是否会将图像存储为 base64 编码的字符串。图像的字符串表示将比二进制表示大得多。SQLite 支持 BLOB 数据类型,所以我会考虑使用它。

于 2012-06-01T15:55:03.140 回答
1

这是 VB.net 中的示例代码:

Imports System.IO
Imports System.Data.SQLite

Public Class Form1

    'Image BLOB Functions:'
    Private Function BlobToImage(ByVal blob)
        Dim mStream As New System.IO.MemoryStream
        Dim pData() As Byte = DirectCast(blob, Byte())
        mStream.Write(pData, 0, Convert.ToInt32(pData.Length))
        Dim bm As Bitmap = New Bitmap(mStream, False)
        mStream.Dispose()
        Return bm
    End Function

    'USE THIS FUNCTION TO CREATE A BLOB FROM AN IMAGE FILE'
   Public Overloads Function ImageToBlob(ByVal id As String, ByVal filePath As String)
        Dim fs As FileStream = New FileStream(filePath, FileMode.Open, FileAccess.Read)
        Dim br As BinaryReader = New BinaryReader(fs)
        Dim bm() As Byte = br.ReadBytes(fs.Length)
        br.Close()
        fs.Close()
        'Create Parm'
        Dim photo() As Byte = bm
        Dim SQLparm As New SQLiteParameter("@image", photo)
        SQLparm.DbType = DbType.Binary
        SQLparm.Value = photo
        Return SQLparm
    End Function

    'USE THIS FUNCTION TO CREATE A BLOB FROM AN IMAGE VARIABLE IN MEMORY'
    Public Overloads Function ImageToBlob(ByVal id As String, ByVal image As Image)
        Dim ms As New MemoryStream
        image.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
        'Create Parm'
        Dim photo() As Byte = ms.ToArray()
        Dim SQLparm As New SQLiteParameter("@image", photo)
        SQLparm.DbType = DbType.Binary
        SQLparm.Value = photo
        Return SQLparm
    End Function

    
    'USE THIS SUB TO CREATE A DB AND TABLE'
    Private Sub btnCreateDB_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim SQLconnect As New SQLiteConnection()
        Dim SQLcommand As New SQLiteCommand
        SQLconnect.ConnectionString = "Data Source = " & Application.StartupPath & "\imgdb.sqlite3;"
        SQLconnect.Open()
        SQLcommand = SQLconnect.CreateCommand
        'SQL Query to Create Table'
        SQLcommand.CommandText = "CREATE TABLE foo(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, description TEXT, image BLOB);"
        SQLcommand.ExecuteNonQuery()
        SQLcommand.Dispose()
        SQLconnect.Close()
    End Sub

    'USE THIS SUB TO INSERT IMAGE INTO SQLITE DB.  IT GETS AN id INTEGER FROM 
    Textbox1'
    Private Sub btnInsertImage_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim d As New OpenFileDialog
        d.Filter = "image (*.png)|*.png|(*.jpg)|*.jpg|All files|*.*"

        If d.ShowDialog() = DialogResult.OK Then
            Dim myimage As Bitmap = Clipboard.GetImage()

            Dim SQLconnect As New SQLite.SQLiteConnection()
            Dim SQLcommand As New SQLiteCommand
            SQLconnect.ConnectionString = "Data Source = " & Application.StartupPath & "\imgdb.sqlite3;"
            SQLconnect.Open()
            SQLcommand = SQLconnect.CreateCommand
            'Insert Image, DO NOT single-quote @image'
            SQLcommand.CommandText = "INSERT INTO foo (id,image) VALUES('" + TextBox1.Text + "', @image)"
            'Define @image'
            SQLcommand.Parameters.Add(ImageToBlob("@image", myimage))
            SQLcommand.ExecuteNonQuery()
            SQLcommand.Dispose()
            SQLconnect.Close()
            MessageBox.Show("Pic Inserted")
        End If
    End Sub

    'USE THIS SUB TO GET THE BLOB FROM THE DB AND CONVERT IT BACK TO AN IMAGE'
    Private Sub btnGetImageFromDB_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Dim SQLconnect As New SQLite.SQLiteConnection()
        Dim SQLcommand As New SQLiteCommand
        SQLconnect.ConnectionString = "Data Source = " & Application.StartupPath & "\imgdb.sqlite3;"
        SQLconnect.Open()
        SQLcommand = SQLconnect.CreateCommand
        SQLcommand.CommandText = "SELECT image FROM foo WHERE id = '" + TextBox1.Text + "'"
        Dim SQLreader As SQLiteDataReader = SQLcommand.ExecuteReader()
        Dim myimage As Bitmap 
        While SQLreader.Read
            myimage = BlobToImage(SQLreader("image"))
            PictureBox1.Image = Nothing
            PictureBox1.Image = myimage
        End While
        SQLcommand.Dispose()
        SQLconnect.Close()
        
    End Sub
于 2021-06-08T22:34:34.453 回答