如何从C#向数据库插入和检索图像?

如何从C#向数据库插入和检索图像?,c#,sql,wpf,C#,Sql,Wpf,我不熟悉WPF编程和Microsoft SQL server。我想在数据库中插入和检索图像。我学习了如何将图像(Windows.Controls.image)转换为byte[]并将其存储到数据库中,但我无法将图像从byte[]转换回image以在WPF窗口中显示 private Image byteArrayToImage(byte[] arr) { MemoryStream stream = new MemoryStream(); stream.Write(arr, 0, ar

我不熟悉WPF编程和Microsoft SQL server。我想在数据库中插入和检索图像。我学习了如何将图像(
Windows.Controls.image
)转换为
byte[]
并将其存储到数据库中,但我无法将图像从
byte[]
转换回
image
以在WPF窗口中显示

private Image byteArrayToImage(byte[] arr)
{
    MemoryStream stream = new MemoryStream();
    stream.Write(arr, 0, arr.Length);
    stream.Position = 0;
    System.Drawing.Image img = System.Drawing.Image.FromStream(stream);    // Exception
    BitmapImage returnImage = new BitmapImage();
    returnImage.BeginInit();
    MemoryStream ms = new MemoryStream();
    img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
    ms.Seek(0, SeekOrigin.Begin);
    returnImage.StreamSource = ms;
    returnImage.EndInit();
    Image ans = new Image();
    ans.Source = returnImage;
    return ans;
}
输出:

System.ArgumentException:'参数无效。'


首先,为PictureHelper创建一个静态类。您必须导入WPF中使用的位图图像,我认为这是使用System.Drawing.Imaging的

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Threading;
using Application = System.Windows.Forms.Application;
using Size = System.Drawing.Size;

public static class PictureHelper 
{
    public static BitmapImage GetImage(object obj)
    {
        try
        {
            if (obj == null || string.IsNullOrEmpty(obj.ToString())) return new BitmapImage();

            #region Picture

            byte[] data = (byte[])obj;

            MemoryStream strm = new MemoryStream();

            strm.Write(data, 0, data.Length);

            strm.Position = 0;

            Image img = Image.FromStream(strm);

            BitmapImage bi = new BitmapImage();

            bi.BeginInit();

            MemoryStream ms = new MemoryStream();

            img.Save(ms, ImageFormat.Bmp);

            ms.Seek(0, SeekOrigin.Begin);

            bi.StreamSource = ms;

            bi.EndInit();

            return bi;

            #endregion
        }
        catch
        {
            return new BitmapImage();
        }
    }

    public static string PathReturner(ref string name)
        {
            string filepath = "";
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Multiselect = false;
            openFileDialog.Filter = @"Image Files(*.jpeg;*.bmp;*.png;*.jpg)|*.jpeg;*.bmp;*.gif;*.png;*.jpg";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.Title = @"Please select an image file to upload.";

            MiniWindow miniWindow = new MiniWindow();
            miniWindow.Show();

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                filepath = openFileDialog.FileName;
                name = openFileDialog.SafeFileName;
            }

            miniWindow.Close();
            miniWindow.Dispose();
            return filepath;
        }

        public static string Encryptor(this string safeName)
        {
            string extension = Path.GetExtension(safeName);

            string newFileName = String.Format(@"{0}{1}{2}", Guid.NewGuid(), DateTime.Now.ToString("MMddyyyy(HHmmssfff)"), extension);
            newFileName = newFileName.Replace("(", "").Replace(")", "");
            return newFileName;
        }


        public static Bitmap ByteToBitmap(this byte[] blob)
        {
            MemoryStream mStream = new MemoryStream();
            byte[] pData = blob;
            mStream.Write(pData, 0, Convert.ToInt32(pData.Length));
            Bitmap bm = new Bitmap(mStream, false);
            mStream.Dispose();
            return bm;

        }

        public static byte[] BitmapToByte(this Image img)
        {
            byte[] byteArray = new byte[0];
            using (MemoryStream stream = new MemoryStream())
            {
                img.Save(stream, ImageFormat.Png);
                stream.Close();

                byteArray = stream.ToArray();
            }
            return byteArray;
        }
}
这是用来检索带有图片的类(在我的例子中是候选类)

public SortableBindingList<Candidate> RetrieveManyWithPicture(Candidate entity)
{
    var command = new SqlCommand { CommandText = "RetrievePictureCandidates", CommandType = CommandType.StoredProcedure };

    command.Parameters.AddWithValue("@CandidateId", entity.CandidateId).Direction = ParameterDirection.Input;


    DataTable dt = SqlHelper.GetData(command); //this is where I retrieve the row from db, you have your own code for retrieving, so make sure it works.

    var items = new SortableBindingList<Candidate>();

    if (dt.Rows.Count <= 0) return items;
    foreach (DataRow row in dt.Rows)
    {
        Candidate item = new Candidate();

        item.CandidateId = row["CandidateId"].GetInt();
        item.LastName = row["LastName"].GetString();
        item.FirstName = row["FirstName"].GetString();

        item.PictureId = row["PictureId"].GetInt();
        item.PhotoType = PictureHelper.GetImage(row["Photo"]); //in my db, this is varbinary. in c#, this is byte[]

        items.Add(item);

    }

    return items;
}
这是保存图片的方法

public bool Insert(Picture entity)
{
    var command = new SqlCommand();

    try
    {
        command.CommandText = "AddPicture";
        command.CommandType = CommandType.StoredProcedure;

        command.Parameters.AddWithValue("@Name", entity.Name).Direction = ParameterDirection.Input;
        command.Parameters.AddWithValue("@Photo", entity.Photo).Direction = ParameterDirection.Input;

        int result = SqlHelper.ExecuteNonQuery(command); //executenonquery will save the params to the db

        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

我编辑了你问题的标题。请不要强制执行问题标题中的标记。看看为什么,你试过这个吗?或者不要在WPF中使用System.Drawing.Image。看一看从中派生的类。
private void UploadButton_Click(object sender, EventArgs e)
{
    string safeName = "";
    string pathName = PictureHelper.PathReturner(ref safeName);
    PictureViewModel vm = new PictureViewModel();
    if (pathName != "")
    {
        safeName = safeName.Encryptor();

        FileStream fs = new FileStream(pathName, FileMode.Open, FileAccess.Read);
        byte[] data = new byte[fs.Length];


        fs.Read(data, 0, Convert.ToInt32(fs.Length));
        fs.Close();

        PicNameLabel.Text = safeName;
        vm.Entity.Name = safeName; //this is the byte[]

        Bitmap toBeConverted = PictureHelper.ByteToBitmap(data); //convert the picture before sending to the db

        vm.Entity.Photo = PictureHelper.BitmapToByte(toBeConverted);
        vm.Entity.Path = pathName;

        CandidatePictureBox.Image = toBeConverted;

        vm.Insert(vm.Entity);

    }
}
public bool Insert(Picture entity)
{
    var command = new SqlCommand();

    try
    {
        command.CommandText = "AddPicture";
        command.CommandType = CommandType.StoredProcedure;

        command.Parameters.AddWithValue("@Name", entity.Name).Direction = ParameterDirection.Input;
        command.Parameters.AddWithValue("@Photo", entity.Photo).Direction = ParameterDirection.Input;

        int result = SqlHelper.ExecuteNonQuery(command); //executenonquery will save the params to the db

        return true;
    }
    catch (Exception)
    {
        return false;
    }
}