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

如何在图像缩放后保存具有原始位深度的图像?

问题

使用以下VB.NET代码对图像进行缩放保存时,原始文件位深度为8bit,但缩放后保存的图像位深度变为24bit,如何实现保存时保留原始位深度?

Dim strFolder = "E:\test\"
Dim oFile = strFolder & "a.png"
If oFile.ToString.ToLower.Contains(".png") Or oFile.ToString.ToLower.Contains(".jpg") Or oFile.ToString.ToLower.Contains(".jpeg") Then
    Dim strFileName = System.IO.Path.GetFileName(oFile)
    Try
        Dim original As Image = Image.FromFile(oFile)
        ' Calculate the scaled dimensions
        Dim w As Integer = CInt(original.Width * 0.9)
        Dim h As Integer = CInt(original.Height * 0.9)
        Dim encoderParams = New EncoderParameters(1)
        encoderParams.Param(0) = New EncoderParameter(Encoder.ColorDepth, 8L)

        Dim resized As Image = New Bitmap(original, New Size(w, h))
        Dim memStream As MemoryStream = New MemoryStream()
        resized.Save(memStream, getCodec("image/jpeg"), encoderParams)
        Dim file As New FileStream(strFolder & "905_" & strFileName, FileMode.Create, FileAccess.Write)
        memStream.WriteTo(file)
        file.Close()
        memStream.Close()
    Catch ex As Exception

    End Try

End If
End Sub

Public Function getCodec(getThis) As Drawing.Imaging.ImageCodecInfo
    Dim output As Drawing.Imaging.ImageCodecInfo
    Dim codecs As Imaging.ImageCodecInfo() = Imaging.ImageCodecInfo.GetImageEncoders
    For Each codec As Imaging.ImageCodecInfo In codecs
        If codec.MimeType = getThis Then
            output = codec
        End If
    Next codec
    Return output
End Function
解决方案

问题原因

  1. 调用New Bitmap(original, New Size(w, h))创建缩放图像时,默认会生成24位RGB格式的Bitmap,直接忽略原始图像的8位像素格式。
  2. 代码强制使用JPEG编码器,但JPEG格式仅支持8位灰度或24位彩色,不支持8位索引色;且编码器参数无法改变Bitmap本身已确定的像素格式。

修改步骤及代码

要保留原始位深度,需在创建缩放图像时指定与原始一致的像素格式,并根据图像类型匹配对应编码器:

Dim strFolder = "E:\test\"
Dim oFile = strFolder & "a.png"
Dim lowerFileName = oFile.ToLower()
If lowerFileName.Contains(".png") Or lowerFileName.Contains(".jpg") Or lowerFileName.Contains(".jpeg") Then
    Dim strFileName = System.IO.Path.GetFileName(oFile)
    Try
        Dim original As Image = Image.FromFile(oFile)
        ' 获取原始图像的像素格式
        Dim originalPixelFormat = original.PixelFormat
        ' 计算缩放尺寸
        Dim w As Integer = CInt(original.Width * 0.9)
        Dim h As Integer = CInt(original.Height * 0.9)

        ' 创建与原始像素格式一致的缩放Bitmap
        Dim resized As New Bitmap(w, h, originalPixelFormat)
        ' 使用Graphics绘制缩放图像,避免自动格式转换
        Using g As Graphics = Graphics.FromImage(resized)
            g.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
            g.DrawImage(original, New Rectangle(0, 0, w, h))
        End Using

        Dim encoderParams As EncoderParameters = Nothing
        Dim codec As Drawing.Imaging.ImageCodecInfo = Nothing

        ' 根据图像类型选择编码器并设置对应参数
        If lowerFileName.Contains(".png") Then
            codec = getCodec("image/png")
            ' 针对PNG的8位索引色设置颜色深度参数
            encoderParams = New EncoderParameters(1)
            encoderParams.Param(0) = New EncoderParameter(Encoder.ColorDepth, 8L)
        Else
            codec = getCodec("image/jpeg")
            ' 针对8位灰度JPEG设置颜色深度与质量参数
            encoderParams = New EncoderParameters(2)
            encoderParams.Param(0) = New EncoderParameter(Encoder.ColorDepth, 8L)
            encoderParams.Param(1) = New EncoderParameter(Encoder.Quality, 90L)
        End If

        ' 使用Using语句自动释放资源
        Using memStream As New MemoryStream()
            resized.Save(memStream, codec, encoderParams)
            Using file As New FileStream(strFolder & "905_" & strFileName, FileMode.Create, FileAccess.Write)
                memStream.WriteTo(file)
            End Using
        End Using

        original.Dispose()
        resized.Dispose()
    Catch ex As Exception
        ' 可添加异常日志记录等处理逻辑
    End Try
End If
End Sub

Public Function getCodec(getThis As String) As Drawing.Imaging.ImageCodecInfo
    For Each codec As Imaging.ImageCodecInfo In Imaging.ImageCodecInfo.GetImageEncoders
        If codec.MimeType = getThis Then
            Return codec
        End If
    Next codec
    Return Nothing
End Function

关键说明

  • 创建Bitmap时指定originalPixelFormat,确保缩放后图像的像素格式与原始一致。
  • 用Graphics.DrawImage完成缩放操作,避免Bitmap构造函数自动转换格式。
  • 区分PNG与JPEG格式选择对应编码器:PNG支持8位索引色,JPEG仅支持8位灰度(若原始为8位灰度JPEG)。
  • 使用Using语句自动释放流与图像资源,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 20:58:32