Improving performance when working on Images with

2019-08-17 10:20发布

问题:

I am trying to speed up various aspects of my website.

The site is a shopping site various search pages which are slow. There are several potential reasons for this, one being working with images.

The other night I created a function which generates a thumbnail for my Facebook OG tags. The function writes a square image to the server 400px x 400px created by tiling the first few (up to 14) product images generated by a search query.

Running this script in total isolation on a test.aspx file gives me reasonable load time, but nothing I can do can speed it up, even when I don't return anything in the browser, just doing this process is taking about 3 seconds, which obviously expanded across the whole live site slows things down.

The entire code is:

Function mergeImgs(idList, imgList, head, fileName) As String

    Try
        Dim maxRows = HttpContext.Current.Request.QueryString("r")
        Dim imgDim = 400
        Dim Image3 As New Bitmap(imgDim, imgDim)
        Dim g As Graphics = Graphics.FromImage(Image3)

        Dim i = 0
        Dim left = 0
        Dim rows = 0
        For Each item In idList
            Dim img = Common.getImageUrl(idList(i), imgList(i), "server", "-tb")
            i += 1
            If img <> "/Images/awaiting.png" Then

                Dim imageData As System.Drawing.Image = System.Drawing.Image.FromFile(img)
                Dim aspect As Double = imageData.Width / imageData.Height ' determine aspect and decide how to display image

                Dim Image1
                Dim fixedHeight = imgDim / maxRows
                Dim objGraphic As System.Drawing.Image = System.Drawing.Image.FromFile(img)

                Dim aspectRatio = objGraphic.Height / objGraphic.Width
                Dim reduction = fixedHeight / objGraphic.Height
                Dim newwidth = objGraphic.Width * reduction
                Image1 = New Bitmap(objGraphic, objGraphic.Width * reduction, fixedHeight)

                g.DrawImage(Image1, New Point(left, fixedHeight * rows))
                If left >= imgDim Then
                    rows += 1
                    left = 0
                ElseIf left < imgDim Then
                    left += newwidth
                ElseIf left < imgDim AndAlso rows = maxRows Then
                    Exit For
                End If
            End If
        Next

        Image3.Save(HttpContext.Current.Server.MapPath("/" & fileName), System.Drawing.Imaging.ImageFormat.Jpeg)

        Return rootUrl & fileName

        g.Dispose()
        g = Nothing

    Catch ex As Exception
        Return ("<P>" & ex.ToString)
    End Try
End Function

There's an external function getImageUrl which is simply a series of logic which writes out a directory structure based on the item ID, this is fast so I doubt holding it up at all.

Variables passed into the function are:

idList = a generic List(of String) ' a list of item IDs
imgList = a generic List(of String) ' a list of image names (image names only stored in DB)
head = the Page.Header ' not actually needed in this prototype, but aimed to allow this to write the OG tag to the Page Header
fileName = simply the name to give the generated image file

I can't help thinking that the section from

Dim imageData As System.Drawing.Image = System.Drawing.Image.FromFile(img)

onwards could potentially be sped up. What this does is work out the aspect ratio of the images loaded, then recalculate the size so they're all the same height so that the tile can be neatly populated in tidy rows.

Dim img = Common.getImageUrl(idList(i), imgList(i), "server", "-tb")

This line loads a thumbnail version ("-tb" in last variable) of the images concerned, so all images being dealt with are approx 50x50px so very small to load and determine the aspect ratios from

There are 4 versions of each image stored on my server, in 4 different sizes for fast display on the website, having messed around with the different images loaded here, it seems to make little difference to the script load time.

Is there anything faster than System.Drawing.Image.FromFile(img) that I can use to load in the images and determine the width and height of it?

There are a couple of other situations on my website where I am required to determine the dimensions of an image and then do something with it and all seem a bit slow.

Any advice most welcome!

Just for info, here's an example of an image generated by the above code

http://www.hgtrs.com/recents.jpg

This is generated from the products returned by this page (which might load slowly!):

http://www.hgtrs.com/search.aspx?Type=recents

I should state the my test.aspx file also includes a call to a database, having tested the query used directly, I get a query time of 0.18 seconds, I dont know how this time expands into a real application. I have optimised this query and the tables (it uses one nested query and a join) as much as I know how.