16

WinForm with CFのアプリを使用して、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の反対を作成するコードがありますが、最初にデータベースからイメージをロードする必要があります。それをするためのアイデアはありますか?

編集チャーリーが提案したように、ブロブを使用して画像を保存しようとしています。私はこのコードを試しました:

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のエラーが発生します。

何か提案はありますか?

解決策このコードは、画像をデータベースに保存してから、画像をロードしてpictureBoxに表示します。

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

データベースから画像をロードするにはselect、他の種類のデータの場合と同じように、SQLステートメントを使用してデータを取得します。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;
}

保存コードと同様に、画像を読み込むための私のサンプルコードでは、テーブルに保存された1つの画像のみを使用します。複数の画像を読み込んで保存するには、IDフィールドをテーブルに挿入してから、SQLステートメントでwhere句を使用する必要があります。select


個人的に、画像を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 に答える