保存&使用XML C#将datagridview中的多个图像byte []代码检索到SQL Server

时间:2014-11-09 17:50:43

标签: c# sql xml datagridview

我正在创建第一个数据表,以便在datagridview中保存图像。

 DataTable dt = new DataTable();
 dt.Columns.Add("Name", typeof(string));//0
 dt.Columns.Add("Upload", typeof(string));//1
 dt.Columns.Add("Show", typeof(string));//2
 dt.Columns.Add("image", typeof(byte[]));//3

 for (int i = 0; i < dgvDemo.RowCount-1; i++)
 {
            DataRow drOLD = dt.NewRow();
            drOLD["image"] =dgvDemo.Rows[i].Cells[3].Value;
            drOLD["Name"] = dgvDemo.Rows[i].Cells[0].Value;
            drOLD["Upload"] = "Upload";
            drOLD["Show"] = "Show";
            dt.Rows.Add(drOLD);
 }

 Image img = PBImage.Image; //Image.FromFile(@"physical path to the file");
 DataRow dr = dt.NewRow();
 dr["image"] = imageToByteArray(img);
 dr["Name"] = "Image";
 dr["Upload"] = "Upload";
 dr["Show"] = "Show";
 dt.Rows.Add(dr);

 dgvDemo.DataSource = dt;

 public byte[] imageToByteArray(System.Drawing.Image imageIn)
 {
        MemoryStream ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
        return ms.ToArray();
 }

这是使用XML作为存储过程参数

在数据库中保存图像的代码
 hash = new Hashtable();
            hash.Add("@QueryNo", QueryNo);
            string strXmlCategory_Section = "";
            StringBuilder xmlClassMaster = new StringBuilder();
              for (int k = 0; k < dgvDemo.Rows.Count-1; k++)
                {
                    xmlClassMaster.Append("<Row>");
                    xmlClassMaster.Append("<Name>" + dgvDemo.Rows[k].Cells[0].Value + "</Name>");
                    xmlClassMaster.Append("<GridImage><cdata>" + ((byte[])dgvDemo.CurrentRow.Cells[3].Value) + "</cdata></GridImage>");
                    xmlClassMaster.Append("</Row>");
                }

                if (xmlClassMaster.Length > 0)
                {
                    xmlClassMaster.Append("</ImageInGrid>");
                    strXmlCategory_Section = "<ImageInGrid>" + Convert.ToString(xmlClassMaster);
                }
                hash.Add("@strImageInGrid", strXmlCategory_Section);

哈希表作为参数列表传递给存储过程。

存储过程代码:

Exec sp_xml_prepareDocument @DocHandle_ImageInGrid output, @strImageInGrid

select Name, GridImage
        into #temp 
        from OPENXML (@DocHandle_ImageInGrid, '/ImageInGrid/Row',12)
        with (

                Name varchar(50) 'Name', 
                GridImage varbinary(max) 'GridImage'

             )

    insert into dbo.GridImage
        ( Name, GridImage)
    Select  Name, GridImage
    From #temp

我从数据库中获取图像时遇到问题。它到网格。

错误是

  

参数无效。在system.drawing.image.fromstream

我认为我的保存方法有误,请帮忙

1 个答案:

答案 0 :(得分:0)

您的方法imageToByteArray()可以返回0到255之间的任何值的字节。您的数据库可能不支持具有此类完全任意字符值的字符串。建议你改为将图像字节转换为base 64:

    public static string ToBase64String(this System.Drawing.Image imageIn)
    {
        if (imageIn == null)
            return null;
        ImageConverter converter = new ImageConverter();
        return Convert.ToBase64String((byte[])converter.ConvertTo(imageIn, typeof(byte[])));
    }

    public static Image FromBase64String(string imageString)
    {
        if (string.IsNullOrEmpty(imageString))
            return null;
        ImageConverter converter = new ImageConverter();
        return (Image)converter.ConvertFrom(Convert.FromBase64String(imageString));
    }

我使用ImageConverter因为它以当前格式保存图像。如果您想将图片保存为特定格式 - 在您的情况下为System.Drawing.Imaging.ImageFormat.Gif - 您的代码是正确的。

更新

看起来你正在犯一个更基本的错误。当你这样做

var s = "<GridImage><cdata>" + ((byte[])dgvDemo.CurrentRow.Cells[3].Value) + "</cdata></GridImage>";

你基本上在做

byte[] byteArray = (byte[])dgvDemo.CurrentRow.Cells[3].Value;
var s = "<GridImage><cdata>" + byteArray + "</cdata></GridImage>";

要执行此添加,.Net会通过调用byteArray方法将ToString()转换为字符串 - 但此方法尚未在数组中重写,只返回类型名称。因此你得到"<GridImage><cdata>System.Byte[]</cdata></GridImage>",这肯定不是你想要的。您需要明确地将字节数组转换为字符串,Convert.ToBase64String()Convert.FromBase64String()为您做。