【问题标题】:working with images as a database table column将图像用作数据库表列
【发布时间】:2010-10-21 05:13:57
【问题描述】:

我有一个数据库(sql server 2008),我正在 Visual Studio 2010 中使用 c#。

我想与我的数据库建立连接。我为此编写了如下代码:

    SqlConnection mySqlConnection = new SqlConnection
    ("Data Source=servername\\SQL2008; Initial Catalog=MyData;UID=MyID;PWD=mypassword;");

    SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
    mySqlCommand.CommandText = "SELECT image_column FROM images_table ";

    mySqlConnection.Open();

    SqlDataReader productsSqlDataReader = mySqlCommand.ExecuteReader();

我不知道该怎么做。我的意思是如何在执行上述语句后从阅读器中提取列?此外,我需要逐行浏览整个列并将每个图像转换为 IContent 项。我是否必须为此编写自己的转换器,或者是否有任何 .NET 类已经这样做了?

这是场景。我有一个大约 20 列的表,其中之一是 images_column。该列是唯一将图像存储为二进制数据的列。剩下的列是与该特定图像关联的通常整数(其大小值)和字符串(其名称、位置等)。我希望现在很清楚。

谢谢。

【问题讨论】:

  • 你能告诉我们IContent是什么吗,这对我们帮助很大。听起来像是一个接口,是否有一个工厂类来创建它们或您可以使用的实际 ImageContent 类?

标签: c# sql sql-server collections


【解决方案1】:

根据您在数据库中保存图像的方式,您可以使用Bitmap 类来提取它们。它的构造函数需要几个不同的参数,例如 Stream。

您可以使用阅读器的Read 函数从阅读器那里获取数据。它给你一个布尔值,让你知道你是否有一个有效的行。您可以在 if 语句或 while 语句中使用它。

例如,将数据库列中的数据馈送到 MemoryStream 并将其提供给 Bitmap 构造函数。

while (productsSqlDataReader.Read()) {
    MemoryStream stream = new MemoryStream((byte[])productsSqlDataReader["image_column"]);
    new Bitmap(stream);
}

【讨论】:

  • 如果列中有超过 1 张图片,这会起作用吗?这看起来像是将整个列作为字节缓冲区是吗?在那种情况下,我如何将每个图像作为一个字节数组?
  • @VP:您在数据库的同一 中有几张图片,还是每行一张图片?如果您在一列中有多个图像,则需要一种确定它们大小的方法,不幸的是,图像处理超出了我的知识范围。如果您在同一个 cell 中确实有多个图像,请问为什么?如果每个单元格有一个图像(即每列和行一个),则在 while 循环的每个循环中都会得到一个。
  • 这是场景。我有一个大约 20 列的表,其中之一是 images_column。该列是唯一将图像存储为二进制数据的列。剩下的列是与该特定图像关联的通常整数(其大小值)和字符串(其名称、位置等)。我希望现在很清楚。谢谢。我也会在主要问题中发布它。
  • @VP:但是您声明“与该特定图像相关联”。您是每行一张图片还是特定单元格中有几张图片?如果每行有一张图片,上述解决方案将起作用。
  • 我每行只有 1 张图片,表格中只有 1 列有图片。
【解决方案2】:
        string conn = "Data Source=servername\\SQL2008; Initial Catalog=MyData;UID=MyID;PWD=mypassword;";
        using (SqlConnection dbConn = new SqlConnection(conn))
        {
            dbConn.Open();
            string sql = "SELECT DATALENGTH(image_column), image_column FROM images_table ";
            using (SqlCommand cmd = new SqlCommand(sql, dbConn))
            {
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        int size = reader.GetInt32(0);
                        byte[] buff = new byte[size];
                        reader.GetBytes(1, 0, buff, 0, size);
                        MemoryStream ms = new MemoryStream(buff, 0, buff.Length);
                        ms.Write(buff, 0, buff.Length);
                        StoreImage(Image.FromStream(ms, true));
                    }
                }
            }
        }

【讨论】:

  • 谢谢 J。看起来很优雅。
【解决方案3】:

从您的问题中我不确定您到底想要完成什么,但要将图像作为Bitmap 与您的读者一起从列中取出,您可以使用以下内容。

while (productsSqlDataReader.Read())
{
    byte[] buf = productsSqlDataReader["image_column"] as byte[];

    using (MemoryStream ms = new MemoryStream(buf))
    {
       Bitmap bmp = Bitmap.FromStream(ms);
       //do whatever with the bitmap BEFORE you dispose the stream
    }
}

【讨论】:

  • 谢谢。我计划使用该图像并将其转换为我的 Web 应用程序的 IContent。 IContent 是一个 Telerik.Cms.Engine(内容管理系统)类,用作各种 Web 功能(如博客、新闻等)的通用接口。通过将其转换为 IContent 项,我以后可以用它做更多的事情。
  • 也许有一种方法可以从字节数组创建 IContent 类?顺便说一句,您将需要调用 Read() 正如帕特里克所说的那样。我把那部分省略了。
  • 史蒂夫,你是不是假设整列只有一张图片??
  • 不确定您所说的整列中的 1 张图片是什么意思。我假设每行每列一张图像,但就像我说的那样,你必须像帕特里克所说的那样调用 Read() 。我编辑显示。
  • 这是场景。我有一个大约有 20 列的表,其中之一是 images_column。该列是唯一将图像存储为二进制数据的列。剩下的列是与该特定图像关联的通常整数(其大小值)和字符串(其名称、位置等)。我希望现在很清楚。谢谢。我也会在主要问题中发布它。 ——
猜你喜欢
  • 2017-09-06
  • 1970-01-01
  • 2020-10-10
  • 1970-01-01
  • 2023-02-09
  • 2010-11-25
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
相关资源
最近更新 更多