winforms 为什么我的图像(来自数据库)在pictureBox中显示不正确?

qvtsj1bj  于 2022-11-16  发布在  其他
关注(0)|答案(3)|浏览(219)

我这样保存图像:

//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);

我通过单击datagridview来检索图像,如下所示:

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);
    }
}

**注意:**我没有在datagridview中显示图像的二进制数据。

保存和更新图像(使用用户记录)工作正常。
将图像保存到数据库后,它无法正常显示。但当我使用OpenFileDialog加载它时,图像显示得很好。
使用OpenFileDialog加载图像:

当我单击datagridview行以查看用户记录时,pictureBox如下所示:

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

6qftjkof

6qftjkof1#

请尝试使用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);
    }
}
xfb7svmp

xfb7svmp2#

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

// 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);
    }
}
8xiog9wr

8xiog9wr3#

下面是一个完整的解决方案,它似乎可以与SQL Server Express/SQL Server一起使用:

注意:当数据库中的表被创建时,列User_Image应该被创建为varbinary(MAX)
从文件读取图像并作为byte[]返回
注意:我已经提供了3种不同的方法来读取图像文件并返回byte[]。GetImageFromFile似乎生成了一个字节数组,它的字节数与原始的相同(用.jpg测试),而GetImageFromFilev2GetImageFromFilev3的字节数较少。更多信息请参见How to convert image to byte array

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中显示图像(例如:图片框1)

Bitmap image = GetImageFromTblEmployeeImageBitmap("12345");

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

}

资源

相关问题