Возврат изображения с измененным размером из базы данных через .ashx - PullRequest
3 голосов
/ 08 августа 2011

Я нашел несколько похожих вопросов по SO и в других местах, но ничего, что вполне соответствует тому, что я ищу (или, может быть, я просто слишком туп, чтобы соединить точки!)

I 'Я хочу вернуть уменьшенное изображение из полноразмерного изображения, хранящегося в базе данных как 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 из привязки изображения, позволяя использовать один и тот же обработчик для полноразмерных и измененных размеров изображений.

Любой совет / помощь будет принята с благодарностью.Идеи об альтернативных подходах (то есть, «вы все делаете неправильно») также были бы очень кстати.

Ответы [ 3 ]

3 голосов
/ 08 августа 2011

Извините, не парень с 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 голос
/ 08 августа 2011

Да, конечно, можно изменить размер на лету.Я бы посоветовал вам просто позволить HttpHandler создать миниатюру по первому запросу, сохраняя ее в базе данных или в виде изображения на сервере.

Для вашего сценария я, вероятно, рассмотрю решение, в котором обработчик принимает параметры высоты / ширины, изменяет размеры изображения и сохраняет его для повторного использования.

1 голос
/ 08 августа 2011

Да, вместо того, чтобы возвращать двоичный файл var непосредственно обратно в ответ, поместите его в объект Bitmap (через поток памяти, созданный из varbinary)

Измените размер BMP, затем сохраните его обратно в памятьпоток через метод сохранения, затем выведите поток памяти обратно в байтовый массив к ответу.

Имейте в виду, что создание экземпляра Bitmap на сервере может быть очень интенсивным в памяти.Если у вас есть несколько запросов одновременно, вы можете столкнуться с «нехваткой памяти».Вероятно, хорошей идеей будет сохранять миниатюры в дБ или на диске при их создании, чтобы вам не приходилось создавать их заново при каждом запросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...