拍摄以下两张照片:
开发版 - IIS7 Windows 7 Pro 64位计算机
实时版本 - IIS7 Windows Server 2008 64位计算机
请注意实时版本是如何“像素化”&看起来质量低,Dev版本却是流畅的,抗锯齿的&看起来很好。这些都是由相同的代码生成的:
' Settings
Dim MaxHeight As Integer = 140
Dim MaxWidth As Integer = 140
Dim WorkingFolderPath As String = "\\server\share\bla\"
Dim AllowedFileExtensions As New ArrayList
AllowedFileExtensions.Add(".jpg")
AllowedFileExtensions.Add(".jpeg")
' Select an image to use from the WorkingFolder
Dim ImageFileName As String = ""
Dim WorkingFolder As New IO.DirectoryInfo(WorkingFolderPath)
Dim SourceImages As IO.FileInfo() = WorkingFolder.GetFiles()
For Each SourceImage As IO.FileInfo In SourceImages
If AllowedFileExtensions.Contains(SourceImage.Extension.ToLower) = True Then
ImageFileName = SourceImage.Name
End If
Next
' Determine path to selected image (if no image was found use a placeholder)
Dim PhysicalPath As String = ""
If ImageFileName = "" Then
' No Image was found, use the filler image
PhysicalPath = Server.MapPath("ProductOfTheMonthMissing.jpg")
Else
' An Image was found, Redirect to it / build path for Thumnailing
If Request.QueryString("FullSize") = "true" Then
Response.Redirect("../share/bla/" & ImageFileName)
Else
PhysicalPath = WorkingFolderPath & ImageFileName
End If
End If
' Load image and output in binary (resizing if necessary)
Using ProductImage As System.Drawing.Image = System.Drawing.Image.FromFile(PhysicalPath)
Dim newWidth As Integer = ProductImage.Width
Dim newHeight As Integer = ProductImage.Height
' Check if selected size is too big, if so, determine new size
If ProductImage.Width > MaxWidth Or ProductImage.Height > MaxHeight Then
Dim ratioX As Double = CDbl(MaxWidth) / ProductImage.Width
Dim ratioY As Double = CDbl(MaxHeight) / ProductImage.Height
Dim ratio As Double = Math.Min(ratioX, ratioY)
newWidth = CInt(ProductImage.Width * ratio)
newHeight = CInt(ProductImage.Height * ratio)
End If
' Create a new bitmap from the image with new size
Dim Codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
Dim CodecInfo As ImageCodecInfo = Nothing
Dim ProductOfTheMonth As New Bitmap(ProductImage, newWidth, newHeight)
Dim ReSizer As Graphics = Graphics.FromImage(ProductOfTheMonth)
ReSizer.InterpolationMode = InterpolationMode.HighQualityBicubic
ReSizer.SmoothingMode = SmoothingMode.HighQuality
ReSizer.PixelOffsetMode = PixelOffsetMode.HighQuality
ReSizer.CompositingQuality = CompositingQuality.HighQuality
' Ensure the encoder uses the best quality settings
Dim EncoderParams As New EncoderParameters(3)
EncoderParams.Param(0) = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L)
EncoderParams.Param(1) = New EncoderParameter(System.Drawing.Imaging.Encoder.ScanMethod, CInt(EncoderValue.ScanMethodInterlaced))
EncoderParams.Param(2) = New EncoderParameter(System.Drawing.Imaging.Encoder.RenderMethod, CInt(EncoderValue.RenderProgressive))
' Set jpeg as the output codec
For Each Codec As ImageCodecInfo In Codecs
If Codec.MimeType = "image/jpeg" Then
CodecInfo = Codec
End If
Next
' Ready a memory stream and byte array
Dim MemStream As New MemoryStream()
Dim bmpBytes As Byte()
' Save the image the the memory stream & prep ContentType for HTTP reasponse
Response.ContentType = "image/jpeg"
ProductOfTheMonth.Save(MemStream, CodecInfo, EncoderParams)
' Flush memory stream into byte array & flush to browser
bmpBytes = MemStream.GetBuffer()
Response.BinaryWrite(bmpBytes)
' Cleanup
ProductOfTheMonth.Dispose()
MemStream.Close()
ProductImage.Dispose()
End Using
这个&的背后原因是什么?我该如何解决这个问题?大概是它在实时网络服务器上的GD问题 - 但我不知道是什么 - 我试图在设置图形和编解码器设置时尽可能彻底但仍然不同?
编辑:源图像在两个示例中也相同(位于中央unc共享位置) - 源图像的副本here
答案 0 :(得分:1)
我已经并且在这里回答了类似的问题:Graphics wrong image interpolation in .Net,但简而言之,似乎不同的平台使用不同的内部算法(或者它可能是GDI中的内部舍入问题)
无论如何,问题出在设置中。请尝试以下方法:
Using s As Bitmap = DirectCast(Bitmap.FromFile(PhysicalPath), Bitmap)
Dim scale As Double = Math.Min(140.0 / s.Width, 140.0 / s.Height)
Using d As New Bitmap(CInt(Math.Floor(scale * s.Width)), CInt(Math.Floor(scale * s.Height)), System.Drawing.Imaging.PixelFormat.Format24bppRgb)
Using dg As Graphics = Graphics.FromImage(d)
dg.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
dg.SmoothingMode = SmoothingMode.HighQuality
dg.PixelOffsetMode = PixelOffsetMode.HighQuality
dg.CompositingQuality = CompositingQuality.HighQuality
dg.Clear(Color.White)
dg.DrawImage(s, New Rectangle(0, 0, d.Width, d.Height), New Rectangle(0, 0, s.Width, s.Height), GraphicsUnit.Pixel)
End Using
Dim jpegArgs As New EncoderParameters(3)
jpegArgs.Param(0) = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L)
jpegArgs.Param(1) = New EncoderParameter(System.Drawing.Imaging.Encoder.ScanMethod, CInt(EncoderValue.ScanMethodInterlaced))
jpegArgs.Param(2) = New EncoderParameter(System.Drawing.Imaging.Encoder.RenderMethod, CInt(EncoderValue.RenderProgressive))
Dim Codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
Dim jpegParams As ImageCodecInfo = Nothing
'#### Set jpeg as the output codec
For Each Codec As ImageCodecInfo In Codecs
If Codec.MimeType = "image/jpeg" Then
jpegParams = Codec
End If
Next
Response.Clear()
Response.ContentType = "image/jpeg"
d.Save(Response.OutputStream, jpegParams, jpegArgs)
End Using
End Using
祝你好运!
答案 1 :(得分:0)
您应该比较所有依赖项并检查IIS是否使用相同的版本。我在这里的信息:How to compare if the configuration is different for IIS?
如果使用相同的配置,那么它可能与图形卡有关,通常服务器没有用于图像处理的特定图形卡。在这种情况下,您应该在开发机器中配置GDI +以不使用加速或卡特定指令。 Using Graphics Card instead of GDI+ for Image Manipulation
可能正在使用其他引擎,并将代码帮助更改为变通方法: Replace GDI+ DrawImage with PInvoked GDI and transparent PNG's
答案 2 :(得分:-1)
您是否在生产环境中使用代理缓存Web服务器,如Apache,Nginex,Varnish ......服务器和客户端之间?
代理服务器具有谷歌页面速度或类似速度等模块,对图像进行压缩以提高下载速度是非常常见的。在这种情况下,编写例外规则应该是微不足道的。