0

前段时间我试图为我的网站后端创建一个图像上传工具。我设法做到了这一点,但在较小的图像上我的图像质量仍然很差。

我需要创建 4 个图像:

  1. 最大缩放图像 1800 x 1800 像素
  2. 显示图像最大 180 x 275 像素
  3. 搜索图像最大 120 x 100 像素
  4. 小缩略图 50 x 50 像素(最大)

我通常在上传之前使用Photoshop或其他工具手动调整大小和图像到1800 x 1800,然后使用下面的代码上传和调整大小(图像都是jpgs)

变量是:

  1. FileName = 最初上传正常
  2. NewFileName = 将调整大小的图像保存为的文件名
  3. maxWidth / maxHeight - 不言自明
  4. uploadDir = 要保存到的目录
  5. 分辨率 = 质量 jpg 分辨率 0-100,我在这些示例中使用 80

     Public Shared Sub ResizeImages(FileName, NewFileName, maxWidth, maxHeight, uploadDir, resolution)
     Try
        Dim originalImg As System.Drawing.Image = System.Drawing.Image.FromFile(uploadDir & FileName)
        Dim aspectRatio As Double
        Dim newHeight As Integer
        Dim newWidth As Integer
       ' Calculate Size '
            If originalImg.Width > maxWidth Or originalImg.Height > maxHeight Then
                If originalImg.Width >= originalImg.Height Then ' image is wider than tall
                    newWidth = maxWidth
                    aspectRatio = originalImg.Width / maxWidth
                    newHeight = originalImg.Height / aspectRatio
                Else ' image is taller than wide
                    newHeight = maxHeight
                    aspectRatio = originalImg.Height / maxHeight
                    newWidth = originalImg.Width / aspectRatio
                End If
            Else ' if image is not larger than max then keep original size
                newWidth = originalImg.Width
                newHeight = originalImg.Height
            End If
    
            Dim newImg As New Bitmap(originalImg, CInt(newWidth), CInt(newHeight)) '' blank canvas
            Dim canvas As Graphics = Graphics.FromImage(newImg) 'graphics element
    
            '*** compress ***'
            Dim myEncoderParameters As EncoderParameters
            myEncoderParameters = New EncoderParameters(1)
            ' set quality level based on "resolution" variable
            Dim myEncoderParameter = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, CType(resolution, Int32))
            myEncoderParameters.Param(0) = myEncoderParameter
    
            canvas.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality
            canvas.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
            canvas.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
    
            canvas.DrawImage(newImg, New Rectangle(0, 0, newWidth, newHeight))
            newImg.Save(uploadDir & (NewFileName), getCodec("image/jpeg"), myEncoderParameters)
    
            '*** Close ***'
            canvas.Dispose()
            originalImg.Dispose()
            newImg.Dispose()
            '*** Nothing ***'
            canvas = Nothing
            newImg = Nothing
            originalImg = Nothing
    
        Catch ex As Exception
            HttpContext.Current.Response.Write(ex.ToString & " " & uploadDir & " " & FileName & " _ " & NewFileName)
        End Try
    
    End Sub
    

为了实现所有四个图像,我将所需的大小作为列表传递,然后循环该列表,按预期文件大小的降序排列,因此,最大的在前,然后我将最近上传的图像作为FileName参数传递给函数这样每次,该功能都会收到一个较小的图像,所以不要像我从阅读各种帖子中意识到的那样尝试将 2000x2000px 图像调整为 50x50px,这样缩小会导致质量下降。

以这种方法运行循环后,我的小缩略图质量非常好,但我的中间图像仍然很差。

在这里,它们按尺寸降序排列:

http://www.hartnollguitars.co.uk/Products2/0/0/0/9/6/57/1347831580.jpg http://www.hartnollguitars.co.uk/Products2/0/0/0/9 /6/57/1347831580-dis.jpg http://www.hartnollguitars.co.uk/Products2/0/0/0/9/6/57/1347831580-se.jpg http://www.hartnollguitars.co .uk/Products2/0/0/0/9/6/57/1347831580-tb.jpg

如您所见,“搜索”和“显示”图像在吉他边缘周围仍然是块状的。

我究竟做错了什么?!

如果我的减少太多,我将如何运行内存中的逐渐减少。

我的意思是,让我印象深刻的是,上面的函数每次都将文件保存到磁盘,这必须占用一些时间,所以如果我要循环一个缩减函数,缩小图像的大小,小在内存中增加(例如每次 10%),然后在减少达到正确大小时将最终图像保存到磁盘。我不确定如何做到这一点。

我正在使用 ASP.NET 2.0 并且对它比较陌生,所以我并不完全了解我可以使用的所有方法。

任何代码示例都会有很大帮助!

谢谢

4

1 回答 1

1

您做错的是您正在使用Bitmap构造函数创建缩小的图像,然后将该图像绘制到自身上。构造Bitmap函数自然不能使用您Graphics稍后在对象中设置的质量设置来调整图像大小,因此质量会很差。

Bitmap相反,您应该使用仅采用大小的构造函数创建一个空白对象:

Dim newImg As New Bitmap(newWidth, newHeight)

然后你应该在画布上绘制原始图像:

canvas.DrawImage(originalImg, New Rectangle(0, 0, newWidth, newHeight))
于 2012-09-16T22:05:04.337 回答