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

3
我在SO和其他地方找到了一些类似的问题,但没有完全满足我所需的(或者可能是我太蠢了,无法连接点!)
我想从数据库中存储的varbinary(max)格式的全尺寸图像中返回缩略图像。我将在画廊式视图中使用这些缩略图像,因此小尺寸/高效加载非常重要。我一直在使用.ashx将全尺寸图像返回到绑定的asp.net Image控件中,代码如下:
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,从而允许同一处理程序用于全尺寸和调整大小的图像。
如有需要,我可以提供进一步的建议/协助。对替代方法的想法(即“您正在错误地处理此问题”)也非常欢迎。

如果你正在编写自己的图像调整大小代码,请阅读此避坑清单。如果可以使用开源库,我的ImageResizing.Net库可以从MS SQL数据库中读取、调整大小和磁盘缓存图像。 - Lilith River
3个回答

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

是的,与其直接将var binary返回到响应中,不如通过从varbinary创建的内存流将其放入Bitmap对象中。

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

请记住,在服务器上实例化Bitmap可能会非常消耗内存。如果您同时有多个请求,可能会遇到“内存不足异常”。最好在创建缩略图时将其保存到数据库或磁盘中,这样您就不必在每个请求上都重新创建它们。


1

是的,动态调整大小肯定是可行的。我建议您让HttpHandler在第一次请求时创建缩略图,并将其存储在数据库中或作为服务器上的图像。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接