【发布时间】:2011-10-12 20:53:59
【问题描述】:
我正在谷歌搜索某种解决方案,我找到了一个,我试图在我的代码中实现它,但它不起作用。问题是,在调整白色图像的大小后,它们会出现灰色边框。
这是我找到的solution的链接:
上面写着: 发生此问题是因为您将图像数据插入到 新尺寸,但沿边缘没有像素可以插值和 .NET 默认情况下,这些边缘使用黑色像素。要解决此问题,您需要使用 您的 DrawImage 调用中的 ImageAttributes 类....
代码 1:这是我实现 ImageAttributes 的代码:
Private Shared Function ResizeImageFile(ByVal imageFile As Byte(), ByVal targetSize As Integer) As Byte()
Using oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(imageFile))
Dim newSize As Size = CalculateDimensions(oldImage.Size, targetSize)
Using newImage As New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)
Using canvas As Graphics = Graphics.FromImage(newImage)
Using ia As New ImageAttributes
ia.SetWrapMode(Drawing2D.WrapMode.TileFlipXY)
canvas.SmoothingMode = SmoothingMode.AntiAlias
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, newImage.Width, newImage.Height, GraphicsUnit.Pixel, ia)
Dim m As New MemoryStream()
newImage.Save(m, ImageFormat.Png)
Return m.GetBuffer()
End Using
End Using
End Using
End Using
End Function
Private Shared Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size
Dim newSize As New Size()
If oldSize.Height > oldSize.Width Then
newSize.Width = CInt((oldSize.Width * (CSng(targetSize) / CSng(oldSize.Height))))
newSize.Height = targetSize
Else
newSize.Width = targetSize
newSize.Height = CInt((oldSize.Height * (CSng(targetSize) / CSng(oldSize.Width))))
End If
Return newSize
End Function
代码 2:在白色图像上产生灰色边框的代码
这是调整大小后的图像:
新的图片宽度 = 400px
Private Shared Function ResizeImageFile(ByVal imageFile As Byte(), ByVal targetSize As Integer) As Byte()
Using oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(imageFile))
Dim newSize As Size = CalculateDimensions(oldImage.Size, targetSize)
Using newImage As New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)
Using canvas As Graphics = Graphics.FromImage(newImage)
canvas.SmoothingMode = SmoothingMode.AntiAlias
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize))
Dim m As New MemoryStream()
newImage.Save(m, ImageFormat.Png)
Return m.GetBuffer()
End Using
End Using
End Using
End Function
Private Shared Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size
Dim newSize As New Size()
If oldSize.Height > oldSize.Width Then
newSize.Width = CInt((oldSize.Width * (CSng(targetSize) / CSng(oldSize.Height))))
newSize.Height = targetSize
Else
newSize.Width = targetSize
newSize.Height = CInt((oldSize.Height * (CSng(targetSize) / CSng(oldSize.Width))))
End If
Return newSize
End Function
更新 30.07.2011.:
CODE 1 解决了白色图像上的灰色边框问题,但存在新问题。问题出在这行代码中:
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, newImage.Width, newImage.Height, GraphicsUnit.Pixel, ia)
使用此代码,我得到具有所需宽度和高度且没有灰色边框的输出图像,但 oldImage 未缩放。
例如:
如果我想上传、调整大小并保存原始图像,例如 640x480 像素,并且 targetSize 为 400 像素。作为输出,我得到一个宽度:400px,高度:300px,没有灰色边框的图像,但 oldImage 未调整大小/缩放为 400px。为此,oldImage 以原始分辨率绘制。 如何缩放 oldImage 以正确绘制?有人可以指出正确的解决方案或修改代码吗?
感谢大家,但我找到了解决所有问题的方法。
CODE 1 无法正常工作,因为以下代码行:
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, newImage.Width, newImage.Height, GraphicsUnit.Pixel, ia)
解决方案:
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, oldImage.Width, oldImage.Height, GraphicsUnit .像素,ia)
这里是完整的工作代码(调整大小的图像,没有灰色/黑色边框):
Private Shared Function ResizeImageFile(ByVal imageFile As Byte(), ByVal targetSize As Integer) As Byte()
Using oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(imageFile))
Dim newSize As Size = CalculateDimensions(oldImage.Size, targetSize)
Using newImage As New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)
Using canvas As Graphics = Graphics.FromImage(newImage)
Using ia As New ImageAttributes
ia.SetWrapMode(Drawing2D.WrapMode.TileFlipXY)
canvas.SmoothingMode = SmoothingMode.AntiAlias
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, oldImage.Width, oldImage.Height, GraphicsUnit.Pixel, ia)
Dim m As New MemoryStream()
newImage.Save(m, ImageFormat.Png)
Return m.GetBuffer()
End Using
End Using
End Using
End Using
End Function
Private Shared Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size
Dim newSize As New Size()
If oldSize.Height > oldSize.Width Then
newSize.Width = CInt((oldSize.Width * (CSng(targetSize) / CSng(oldSize.Height))))
newSize.Height = targetSize
Else
newSize.Width = targetSize
newSize.Height = CInt((oldSize.Height * (CSng(targetSize) / CSng(oldSize.Width))))
End If
Return newSize
End Function
【问题讨论】:
-
不确定问题是什么。您遇到了问题并找到了解决方案。
-
@Antonio,您能否提供一个不起作用的示例图像以及
newSize的尺寸,以便我们看到您所看到的。我尝试了您提供的代码,但没有发现问题。 (虽然从技术上讲,我不会真正将其称为调整图像大小,但您实际上只是在更大的画布上绘制旧图像。) -
Here's a good article on image resizing pitfalls 如果您遇到更多问题。另外,你见过imageresizing.net吗?如果您要为 ASP.NET 项目执行此操作,这很重要..
-
如果您有工作代码,我相信您应该将其作为答案发布并将其标记为正确,这样这个问题就不会再出现在未回答的情况下,并且如果人们更容易将其用作参考通过 Google 或其他方式找到此页面。
标签: asp.net vb.net image resize