我像这样保存我的图像:
//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 加载图像:
当我单击 datagridview 行查看用户记录时,图片框如下所示:
为什么会出现某种分裂?我还没有看到任何类似的问题/解决方案。其中大部分是关于“将图像从数据库加载到pictureBox”。但我已经这么做了。
尝试使用 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);
}
}
这是一个完整的解决方案,它似乎适用于 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();
}
资源:
这是我从数据库获取图像的方法
// 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);
}
}