65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 从数据库保存和加载图像

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.57/5 (40投票s)

2009年2月13日

CPOL

3分钟阅读

viewsIcon

457311

downloadIcon

18342

使用 C# 将图像保存到数据库并在 aspx 页面中加载

引言

本文介绍了如何在 C# 应用程序中上传图像,将其保存在数据库中,并在另一个 aspx 页面中显示它。

背景

HTML img 标签和 C# 中的 Image 控件总是寻找硬盘上或服务器上某个物理位置的图像。本文展示了如何通过将图像源指定为另一个返回图像的 aspx 文件来克服这一点。

将所有图像存储在硬盘上并对其建立索引可能不可行。 读写硬盘也需要更多时间。 因此,如果您的应用程序在动态页面中使用更多图像,则将图像存储在数据库中是最佳选择。

本文介绍如何显示数据库中的动态图像,如何将图像转换为 bytearray 以及如何使用通用处理程序。

Using the Code

首先,必须将上传的图像保存在数据库中。

图像上传

可以使用 Fileupload 控件和上传页面中的提交按钮轻松实现上传功能。

<asp:FileUpload runat="server" ID="flImage" />
<asp:Button runat="server" ValidationGroup="Details" ID="btnSubmit" Text="Upload"
    onclick="btnSubmit_Click" />

必须将从 fileupload 控件中选择的图像存储在 msg 表中。 假设 msg 表有两个字段

表名: msg

字段名 数据类型 主键 可空
msgid int
pic1 blob

如果需要,将 msgid 设置为自动递增字段,这样可能不需要更新它。

在提交按钮的 click 事件中,在 msg 表中插入一条记录。

在插入表之前,必须将所选图像转换为 byte 数组。

private byte[] ConvertImageToByteArray(System.Drawing.Image imageToConvert,
                                       System.Drawing.Imaging.ImageFormat formatOfImage)
{
    byte[] Ret;
    try
    {
        using (MemoryStream ms = new MemoryStream())
        {
            imageToConvert.Save(ms, formatOfImage);
            Ret = ms.ToArray();
        }
    }
    catch (Exception) { throw; }
    return Ret;
}

在提交按钮的 click 事件中,通过调用...在 Image 对象中获取所选图像。

System.Drawing.Image.FromStream(flImage.PostedFile.InputStream) 

...并将其存储在 image 对象中。 必须将此 image 对象转换为 byte 数组才能存储在 blob 字段中。 这是通过调用上面的 ConvertImageToByteArray() 函数完成的。

现在在按钮 click 事件中设置数据库连接,并使用我们从 ConvertImageToByteArray() 函数中获得的 bytearray 更新 msg 表的 pic1 字段。

//Upload image to database
protected void btnSubmit_Click(object sender, EventArgs e)
{
    System.Drawing.Image imag = System.Drawing.Image.FromStream(
        flImage.PostedFile.InputStream);
    System.Data.SqlClient.SqlConnection conn = null;
    try
    {
        try
        {
            conn = new System.Data.SqlClient.SqlConnection(
                ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);
            conn.Open();
            System.Data.SqlClient.SqlCommand insertCommand =
                new System.Data.SqlClient.SqlCommand(
                "Insert into [msg] (msgid, pic1) Values (1, @Pic)", conn);
            insertCommand.Parameters.Add("Pic", SqlDbType.Image, 0).Value =
                ConvertImageToByteArray(imag, System.Drawing.Imaging.ImageFormat.Jpeg);
            int queryResult = insertCommand.ExecuteNonQuery();
            if (queryResult == 1)
                lblRes.Text = "msg record Created Successfully";
        }
        catch (Exception ex)
        {
            lblRes.Text = "Error: " + ex.Message;
        }
    }
    finally
    {
        if (conn != null)
            conn.Close();
    }
}

用于显示图像的通用处理程序

众所周知,aspx 图像控件在其 ImageUrl 属性中查找 Image 文件的物理位置。 诀窍是指定另一个专用处理程序文件,该文件将充当图像。 此处理程序 (ImgHandler.ashx) 不会具有任何 HTML 装饰,因为我们不会单独显示此页面,而是将其用作图像。 为此,必须修改其 ProcessRequest 事件以从数据库读取图像并将图像作为响应返回。

ProcessRequest 事件调用 Response.BinaryWrite() 函数将使此 ashx 处理程序被调用 aspx 页面视为图像。

public void ProcessRequest (HttpContext context)
{
        System.Data.SqlClient.SqlDataReader rdr = null;
        System.Data.SqlClient.SqlConnection conn = null;
        System.Data.SqlClient.SqlCommand selcmd = null;
        try
        {
          conn = new System.Data.SqlClient.SqlConnection
		(System.Configuration.ConfigurationManager.ConnectionStrings
		["ConnectionString"].ConnectionString);
          selcmd = new System.Data.SqlClient.SqlCommand
		("select pic1 from msg where msgid=" + 
		context.Request.QueryString["imgid"], conn);
          conn.Open();
          rdr = selcmd.ExecuteReader();
          while (rdr.Read())
          {
            context.Response.ContentType = "image/jpg";
            context.Response.BinaryWrite((byte[])rdr["pic1"]);
          }
          if (rdr != null)
            rdr.Close();
        }
        finally
        {
          if (conn != null)
              conn.Close();
        }
}

在上面的代码中,请注意 ProcessRequest 事件打开数据库并加载图像,图像 ID 与从请求查询字符串发送的图像 ID 匹配。

此代码仅以 JPG 格式保存和检索图像。 尽管其他图像格式(如 GIF、PNG、BMP 等)可以使用相同的代码,但如果所有其他图像格式都读取为 JPG 格式,则图像质量将无法得到保证。 必须更新此代码以处理不同的图像格式,同时写入数据库并在响应中设置内容类型。

显示图像

现在可以通过将 ImageUrl 设置为上述处理程序,从任何 aspx 页面访问它。

  <asp:Image ID="picone" ImageUrl="ImgHandler.ashx?imgid=1" runat="server" />

imgid 作为查询字符串发送到 ImgHandler.ashx,以便从数据库中获取正确的图像并显示它。

关注点

C# 中的 Image 控件期望 ImageUrl,它是服务器中的物理图像。 本文展示了使 ashx 处理程序表现得像物理图像的解决方法。 它还提供了将图像保存和检索到数据库和从数据库中保存和检索图像的所有相关代码。 本文展示了代码中纯 SQL 中的数据库访问,以便快速理解。 这些 SQL 语句必须受到保护,以防止黑客进行 SQL 注入。

祝您编码愉快!

历史

  • 2009 年 2 月 13 日:初始帖子
© . All rights reserved.