You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VS2010(VB.Net)中JPG缩放保存后颜色变暗的解决方法咨询

解决JPG缩放后颜色暗淡的问题

这个问题我之前在VB.NET项目里也踩过坑!颜色变暗、饱和度降低的核心原因是System.Drawing.Graphics默认启用了颜色管理(ICM),会自动根据系统颜色配置文件调整图像颜色,再加上Bitmap创建和JPEG编码器的默认行为,最终导致原图的鲜亮色彩被削弱。咱们一步步修改代码来解决:

核心修改点

1. 禁用Graphics的自动颜色校正

创建绘图对象后,必须关闭颜色管理相关设置,避免它自动转换颜色。同时把插值模式换成更高质量的HighQualityBicubic,缩放后的细节和色彩会更接近原图:

objGraphics = Graphics.FromImage(imgJPEG_New)
With objGraphics
    .SmoothingMode = Drawing2D.SmoothingMode.HighQuality
    .InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic ' 替换原High模式
    .PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
    .CompositingQuality = Drawing2D.CompositingQuality.HighQuality
    .CompositingMode = Drawing2D.CompositingMode.SourceCopy ' 避免颜色混合失真
    .ImageRenderingFormat = Imaging.PixelFormat.Format24bppRgb ' 强制使用RGB格式
    .DrawImage(imgJPEG_Current, 0, 0, imgJPEG_New.Width, imgJPEG_New.Height)
    .Dispose()
End With

2. 显式指定Bitmap的像素格式

不要直接复用原图像的像素格式(有些JPG可能带有特殊标记),显式指定Format24bppRgb可以确保色彩空间一致:

imgJPEG_New = New Bitmap(
    CInt(imgJPEG_Current.Width * dblRatio), 
    CInt(imgJPEG_Current.Height * dblRatio), 
    Imaging.PixelFormat.Format24bppRgb ' 显式指定24位RGB
)

3. 加载图片时跳过颜色配置文件

Image.FromFile默认会加载图像嵌入的颜色配置文件,导致后续绘图时自动校正颜色。改用Bitmap.FromStream并禁用颜色管理:

' 替换原Image.FromFile代码
Using fs As New FileStream(strFilePhysicalPath_Original, FileMode.Open, FileAccess.Read)
    imgJPEG_Current = Bitmap.FromStream(fs, False, False) ' 最后一个False禁用颜色管理
End Using

4. 优化编码器参数

你的现有参数已经设置了高质量,但可以补充Encoder.ColorTransform参数来确保颜色空间不被转换:

' 先调整编码器参数数量为4
Dim arrEncoderParameters = New Imaging.EncoderParameters(4)
With arrEncoderParameters
    .Param(0) = New Imaging.EncoderParameter(Imaging.Encoder.Quality, 100L)
    .Param(1) = New Imaging.EncoderParameter(Imaging.Encoder.ColorDepth, 24)
    .Param(2) = New Imaging.EncoderParameter(Imaging.Encoder.Compression, Imaging.EncoderValue.CompressionNone)
    .Param(3) = New Imaging.EncoderParameter(Imaging.Encoder.ColorTransform, Imaging.EncoderValue.ColorTransformNone)
End With

修改后的完整代码片段

'***************************************
' Constants
'***************************************
Const DECREASE_RATIO As Double = 10.0
'***************************************
' Initialize Variables
'***************************************
Dim dblRatio As Double = (100 - DECREASE_RATIO) * 0.01
Dim objGraphics As System.Drawing.Graphics
Dim imgJPEG_Current As System.Drawing.Image = Nothing
Dim imgJPEG_New As System.Drawing.Bitmap = Nothing
Dim objJPGCodec As Imaging.ImageCodecInfo = Nothing
' 调整编码器参数数量为4
Dim arrEncoderParameters = New Imaging.EncoderParameters(4)
'***************************************
' Default Values
'***************************************
With arrEncoderParameters
    .Param(0) = New Imaging.EncoderParameter(Imaging.Encoder.Quality, 100L)
    .Param(1) = New Imaging.EncoderParameter(Imaging.Encoder.ColorDepth, 24)
    .Param(2) = New Imaging.EncoderParameter(Imaging.Encoder.Compression, Imaging.EncoderValue.CompressionNone)
    .Param(3) = New Imaging.EncoderParameter(Imaging.Encoder.ColorTransform, Imaging.EncoderValue.ColorTransformNone)
End With
'***************************************
' Get JPEG Codec
'***************************************
For Each objCodec As Imaging.ImageCodecInfo In Imaging.ImageCodecInfo.GetImageDecoders()
    If (objCodec.FormatID = Imaging.ImageFormat.Jpeg.Guid) Then
        objJPGCodec = objCodec
        Exit For
    End If
Next
'***************************************
' Load Current Image To Process (禁用颜色管理)
'***************************************
Using fs As New FileStream(strFilePhysicalPath_Original, FileMode.Open, FileAccess.Read)
    imgJPEG_Current = Bitmap.FromStream(fs, False, False)
End Using
'***************************************
' Create Clone Of Current Image Resized Using New Size Ratio
'***************************************
imgJPEG_New = New Bitmap(
    CInt(imgJPEG_Current.Width * dblRatio), 
    CInt(imgJPEG_Current.Height * dblRatio), 
    Imaging.PixelFormat.Format24bppRgb
)
objGraphics = Graphics.FromImage(imgJPEG_New)
With objGraphics
    .SmoothingMode = Drawing2D.SmoothingMode.HighQuality
    .InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
    .PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
    .CompositingQuality = Drawing2D.CompositingQuality.HighQuality
    .CompositingMode = Drawing2D.CompositingMode.SourceCopy
    .ImageRenderingFormat = Imaging.PixelFormat.Format24bppRgb
    .DrawImage(imgJPEG_Current, 0, 0, imgJPEG_New.Width, imgJPEG_New.Height)
    .Dispose()
End With
'***************************************
' Save New JPG File To Disk
'***************************************
imgJPEG_New.Save(strFilePhysicalPath_Delta, objJPGCodec, arrEncoderParameters)
' 记得释放资源!
imgJPEG_Current.Dispose()
imgJPEG_New.Dispose()

额外提醒

别忘了在代码最后手动释放imgJPEG_Current和imgJPEG_New的资源,避免内存泄漏。这样修改后,缩放后的JPG颜色应该和原图几乎一致,同时保持小尺寸。

内容的提问来源于stack exchange,提问作者TekkGuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:34:17