通过.ashx从数据库返回重新调整大小的图像

时间:2011-08-08 17:45:55

标签: asp.net vb.net image

我在SO和其他地方发现了一些类似的问题,但没有什么可以解决我正在寻找的问题(或者,也许我只是太愚蠢地连接点了!)

我希望从数据库中存储为varbinary(max)的全尺寸图像中返回缩略图。我将在画廊风格的视图中使用缩略图,因此小尺寸/高效负载是至关重要的。我一直在使用.ashx将完整大小的图像返回到绑定的asp.net图像控件,使用以下代码:

Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

    Dim conn As New SqlConnection()
    conn.ConnectionString = *connectionstring*

    Dim cmd As New SqlCommand()
    cmd.Connection = conn
    cmd.CommandType = CommandType.StoredProcedure
    cmd.CommandText = "GetEmplHeadShot"

    Dim emplID As New SqlParameter("@emplID", context.Request.QueryString("emplid"))
    cmd.Parameters.Add(emplID)

    conn.Open()

    Dim myReader As SqlDataReader = cmd.ExecuteReader
    If myReader.Read Then

        context.Response.BinaryWrite(myReader("HeadShot"))
        context.Response.ContentType = "image/jpeg"

    End If
    myReader.Close()
    conn.Close()

End Sub

我意识到最好在上传时解决重新调整尺寸,并将较小的图像存储为离散列。 但与此同时,是否可以对处理程序进行编程以便动态调整图像大小?理想情况下,我可以传递一个额外的查询字符串参数,类似于图像中的isResized绑定,允许相同的处理程序用于完整大小和重新调整大小的图像。

非常感谢任何建议/协助。关于替代方法的想法(即“你这一切都是错的”)也是非常受欢迎的。

3 个答案:

答案 0 :(得分:3)

对不起,不是一个VB人,但如果你能阅读C#,这里有一个例子。您需要为缺少的参数添加一些处理等,但这可以概述您的基本方法。

        public void ProcessRequest( HttpContext context )
        {
            int height = Convert.ToInt32(context.Request["height"]);
            int width = Convert.ToInt32(context.Request["width"]);


            //Get image from database here, put into a stream
            var stream = new MemoryStream(); //this would represent the stream from your database image

            using( var original = Image.FromStream( stream ) )
            {
                using( var resized = new Bitmap(width, height, PixelFormat.Format24bppRgb) )
                {
                    using( var g = Graphics.FromImage( resized ) )
                    {
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        g.PixelOffsetMode = PixelOffsetMode.HighQuality;

                        g.DrawImage( original, new Rectangle( new Point( 0, 0 ), new Size(width, height) ) );

                        var resizedStream = new MemoryStream();
                        resized.Save(resizedStream, ImageFormat.Jpeg);

                        context.Response.ContentType = "image/jpeg";
                        context.Response.BinaryWrite(resizedStream.GetBuffer());
                        context.Response.End();
                    }
                }               
            }

        }

答案 1 :(得分:1)

是的,不是将var二进制文件直接返回给响应,而是将其放入Bitmap对象(通过varbinary创建的内存流)

调整BMP大小,然后通过save方法将其保存回内存流,然后将内存流输回到响应的字节数组中。

请记住,虽然在服务器上实例化Bitmap可以非常记忆内存。如果您同时有多个请求,则可能会遇到“内存不足异常”。在创建时将缩略图保存到数据库或磁盘可能是个好主意,这样您就不必在每次请求时都重新创建缩略图。

答案 2 :(得分:1)

是的,当然可以动态调整大小。我建议你让HttpHandler在第一个请求上创建缩略图,将其存储在数据库中或作为服务器上的图像存储。

对于您的场景,我可能会考虑一种解决方案,其中处理程序接收高度/宽度参数,调整图像大小并存储以供重用。