为什么我的图像(来自数据库)无法在我的图片框中正确显示?

问题描述 投票:0回答:3

我像这样保存我的图像:

//This is in my ImageConverter class:
public static byte[] ConvertImageToByteArray(Image userImage) //Get bytes of the image
{
    using (MemoryStream ms = new MemoryStream())
    using (Bitmap tempImage = new Bitmap(userImage))
    {        
        tempImage.Save(ms, userImage.RawFormat);
        return ms.ToArray();
    }
}       

//this is in my save button:
sqlCmd.Parameters.Add("@user_image", SqlDbType.VarBinary, 8000).Value = 
    ImageConverter.ConvertImageToByteArray(pictureBox1.Image);

我通过单击数据网格视图来检索图像,如下所示:

private void dgvEmpDetails_CellClick(object sender, DataGridViewCellEventArgs e)
{
    try
    {
        if (e.RowIndex != -1)
        {
            //Display user image
            using (SqlConnection con = new SqlConnection(connectionStringConfig))
            using (SqlCommand sqlCmd = new SqlCommand(
                "SELECT user_image FROM dbo.Employee_Image 
                 WHERE employee_id=@employee_id", con))
            {
                con.Open();
                sqlCmd.Parameters.Add("@employee_id", 
                    SqlDbType.NVarChar).Value = EmployeeId;

                using (SqlDataReader reader = sqlCmd.ExecuteReader())
                {
                    if (reader.HasRows)
                    {
                        reader.Read();
                        pictureBox1.Image = ImageConverter.
                            ConvertByteArrayToImage((byte[])(reader.GetValue(0)));
                    }
                    else
                    {
                        pictureBox1.Image = null;
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Something is wrong with the selected record! 
            \nError: { ex.Message  }");
    }
}       

//This is in my ImageConverter class:
public static Image ConvertByteArrayToImage(byte[] buffer) //Get image from database
{
    using (MemoryStream ms = new MemoryStream(buffer))
    {
        return Image.FromStream(ms);
    }
}      

注意: 我不在数据网格视图中显示图像的二进制数据。

保存和更新图像(带有用户记录)效果很好。

将图像保存到数据库后,无法正常显示。但是当我使用 OpenFileDialog 加载它时,图像显示得很好。

使用 OpenFileDialog 加载图像:

enter image description here

当我单击 datagridview 行查看用户记录时,图片框如下所示:

enter image description here

为什么会出现某种分裂?我还没有看到任何类似的问题/解决方案。其中大部分是关于“将图像从数据库加载到pictureBox”。但我已经这么做了。

c# winforms picturebox localdb
3个回答
0
投票

尝试使用 MemoryStream.Write 方法。

更改此:

//This is in my ImageConverter class:
public static Image ConvertByteArrayToImage(byte[] buffer) //Get image from database
{
    using (MemoryStream ms = new MemoryStream(buffer))
    {
        return Image.FromStream(ms);
    }
} 

对此:

//This is in my ImageConverter class:
public static Image ConvertByteArrayToImage(byte[] buffer) //Get image from database
{
    using (MemoryStream ms = new MemoryStream)
    {
        ms.Write(buffer.ToArray(), 0, buffer.Length);
        return Image.FromStream(ms);
    }
} 

0
投票

这是一个完整的解决方案,它似乎适用于 SQL Server Express/SQL Server:

注意:创建数据库中的表时,列

User_Image
应创建为
varbinary(MAX)

从文件中读取图像并以 byte[] 形式返回:

注意:我提供了 3 种不同的方法来读取图像文件并返回 byte[]。

GetImageFromFile
似乎会生成一个与原始字节数相同的字节数组(使用 .jpg 测试),而
GetImageFromFilev2
GetImageFromFilev3
的字节数较少。有关更多信息,请参阅如何将图像转换为字节数组

public static byte[] GetImageFromFile(string filename)
{
    byte[] rawData = null;

    try
    {
        if (!String.IsNullOrEmpty(filename) && System.IO.File.Exists(filename))
        {
            using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                //get length of file - in bytes
                int fileLength = (int)fs.Length;

                //create new byte array
                rawData = new byte[fileLength];

                //read data into byte array (rawData)
                fs.Read(rawData, 0, fileLength);
                fs.Flush();

                Debug.WriteLine("rawData.Length: " + rawData.Length);
            }
        }
    }
    catch (Exception ex)
    {
        //ToDo: log message
        throw ex;
    }

    return rawData;
}

public static byte[] GetImageFromFilev2(string filename)
{
    byte[] rawData = null;

    try
    {
        if (!String.IsNullOrEmpty(filename) && System.IO.File.Exists(filename))
        {
            using (Image image = Image.FromFile(filename))
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    image.Save(ms, image.RawFormat);
                    rawData = ms.ToArray();
                }
            }
        }
    }
    catch (Exception ex)
    {
        //ToDo: log message
        throw ex;
    }

    return rawData;
}

public static byte[] GetImageFromFilev3(string filename)
{
    byte[] rawData = null;

    try
    {
        if (!String.IsNullOrEmpty(filename) && System.IO.File.Exists(filename))
        {
            using (Image image = Image.FromFile(filename))
            {
                ImageConverter ic = new ImageConverter();

                rawData = (byte[])ic.ConvertTo(image, typeof(byte[]));
                Debug.WriteLine("rawData.Length: " + rawData.Length);
            }   
        }
    }
    catch (Exception ex)
    {
        //ToDo: log message
        throw ex;
    }

    return rawData;
}

从数据库读取图像数据:

public static System.Drawing.Bitmap GetImageFromTblEmployeeImageBitmap(string employee_id)
{
    System.Drawing.Bitmap image = null;
    byte[] imageData = GetImageFromTblEmployeeImageByte(employee_id);

    //convert to Bitmap
    if (imageData != null)
    {
        using (System.IO.MemoryStream ms = new System.IO.MemoryStream(imageData))
        {
            image = new System.Drawing.Bitmap(ms);
            ms.Flush();
        }
    }

    return image;
}

public static byte[] GetImageFromTblEmployeeImageByte(string employee_id)
{ 
    byte[] imageData = null;

    try
    {
        using (SqlConnection cn = new SqlConnection(ConnectStr))
        {
            string sqlText = "Select user_image from Employee_Image where employee_id = @employee_id";

            //open connection to db
            cn.Open();

            using (SqlCommand cmd = new SqlCommand(sqlText, cn))
            {
                cmd.Parameters.Add("@employee_id", SqlDbType.NVarChar).Value = employee_id;

                //execute
                SqlDataReader dr1 = cmd.ExecuteReader();

                bool result = dr1.Read();

                if (result)
                {
                    imageData = (byte[])dr1["User_Image"];
                }

                Debug.WriteLine("result: " + result);
            }
        }
    }
    catch (SqlException ex)
    {
        //ToDo: log message
        throw ex;
    }
    catch (Exception ex)
    {
        //ToDo: log message
        throw ex;
    }

    return imageData;
}

将图像数据保存到数据库

public static string SaveImageToTblEmployeeImage(string employee_id, string filename)
{
    return SaveImageToTblEmployeeImage(employee_id, GetImageFromFile(filename));
}

public static string SaveImageToTblEmployeeImage(string employee_id, byte[] user_image)
{
    string status = string.Empty;

    using (SqlConnection cn = new SqlConnection(ConnectStr))
    {
        string sqlText = "INSERT INTO Employee_Image(Employee_Id, User_Image) VALUES (@employee_id, @user_image)";

        //open connection to db
        cn.Open();

        using (SqlCommand cmd = new SqlCommand(sqlText, cn))
        {
            //add parameters
            cmd.Parameters.Add("@employee_id", System.Data.SqlDbType.NVarChar).Value = employee_id;

            //for varbinary(max) specify size = -1, otherwise there is an 8000 byte limit
            //see https://learn.microsoft.com/en-us/dotnet/api/system.data.sqldbtype?view=netframework-4.8
            cmd.Parameters.Add("@user_image", System.Data.SqlDbType.VarBinary, -1).Value = user_image;

            //execute
            int numRowsAffected = cmd.ExecuteNonQuery();
            status = "Data inserted into table 'Employee_Image'";

            Debug.WriteLine("numRowsAffected: " + numRowsAffected);
        }
    }

    return status;
}

将图像上传至数据库

using (OpenFileDialog ofd = new OpenFileDialog())
{
    ofd.Filter = "Image Files (*.bmp;*.gif;*.jpg;*.jpeg;*.png)|*.bmp;*.gif;*.jpg;*.jpeg;*.png|All Files (*.*)|*.*";

    if (ofd.ShowDialog() == DialogResult.OK)
    {
        SaveImageToTblEmployeeImage("12345", ofd.FileName);
    }
}

在 PictureBox 中显示图像(例如:pictureBox1)

Bitmap image = GetImageFromTblEmployeeImageBitmap("12345");

if (image != null)
{
    pictureBox1.Image = image;
    pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; //fit to size
    pictureBox1.Refresh();

}

资源


0
投票

这是我从数据库获取图像的方法

// This method use to update the form.
private void loadFormWithID(int ID)
{
    dbServer conn = new dbServer(sysController.getConn);
    DataTable tbl = conn.getQueryList("SELECT * FROM Products WHERE ID = " + ID);
    DataRow row = tbl.Rows[0];      
    // This is how i update the Picture Box
    pictureBoxItem.Image = row["Image"] == DBNull.Value ? pictureBoxItem.InitialImage : ImageController.bytesToImage((byte[])row["Image"]);  
 }

这是我与数据库通信的 dbserver 类。

public class dbServer
{
    public string _connectionLink;

    public dbServer(string connectionString)
    {
        _connectionLink = connectionString; 
    }

    public DataTable getQueryList(string sqlQuery)
    {
         DataTable tbl = new DataTable();

       using (SqlConnection conn = new SqlConnection(_connectionLink))
       {
           using (SqlCommand cmd = new SqlCommand(sqlQuery, conn))
            {
               conn.Open();
               SqlDataReader reader = cmd.ExecuteReader();
               tbl.Load(reader);
            }
        }
        return tbl;
    }
}

这是我用于数据库图像检索器的。

class ImageController
{
    public static byte[] ImageToBytes(PictureBox pb)
    {
        MemoryStream ms = new MemoryStream();
        pb.Image.Save(ms, pb.Image.RawFormat);
        return ms.GetBuffer();
    }

    public static byte[] ImageToBytes(Image pb)
    {
        MemoryStream ms = new MemoryStream();
        pb.Save(ms, pb.RawFormat);
        Console.WriteLine(ms.Length);
        return ms.GetBuffer();
    } 

    public static Image bytesToImage(byte[] imageRaw)
    {
        MemoryStream ms = new MemoryStream(imageRaw);
        return Image.FromStream(ms);
    }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.