不久前,我试图为我的网站后端创建一个图像上传工具。我设法做到了这一点,但在较小的图像上,我的图像质量仍然很差。
我需要创建4个图像:
- 缩放图像最大1800 x 1800像素
- 显示图像最大180 x 275px
- 搜索图像最大120 x 100px
- 小缩略图最大50 x 50像素
我通常在上传之前用Photoshop或其他东西手动调整大小并将图像调整到1800 x 1800,然后使用下面的代码上传并调整大小(图像都是jpgs)
变量为:
- FileName=最初上传良好
- NewFileName=将调整大小的图像另存为的文件名
- maxWidth/maxHeight-不言自明
- uploadDir=要保存到的目录
-
分辨率=质量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.jpghttp://www.hartnollguitars.co.uk/Products2/0/0/0/9/6/57/1347831580-dis.jpghttp://www.hartnollguitars.co.uk/Products2/0/0/0/9/6/57/1347831580-se.jpghttp://www.hartnollguitars.co.uk/Products2/0/0/0/9/6/57/1347831580-tb.jpg
正如你所看到的,"搜索"one_answers"显示"图像在吉他的边缘仍然是块状的。
我做错了什么?!
如果我的缩减幅度很大,我该如何进行内存中的逐步缩减。
我的意思是,我突然想到,上面的函数每次都会将文件保存到光盘上,这肯定需要一些时间,所以如果我要循环一个缩小函数,在内存中以小增量(比如每次10%)缩小图像的大小,然后在缩小到正确大小时将最终图像保存到光盘。不过我不知道该怎么做。
我使用的是ASP.NET 2.0,对它还比较陌生,所以我并不完全了解所有可用的方法。
任何代码示例都会有很大帮助!
感谢
错误的是,您使用Bitmap
构造函数创建了一个缩小的图像,然后将该图像绘制到其自身上。Bitmap
构造函数自然不能使用您稍后在Graphics
对象中设置的质量设置来调整图像大小,因此质量会很差。
相反,您应该创建一个空的Bitmap
对象,该对象的构造函数只采用以下大小:
Dim newImg As New Bitmap(newWidth, newHeight)
然后你应该在画布上绘制原始图像:
canvas.DrawImage(originalImg, New Rectangle(0, 0, newWidth, newHeight))