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

基于VB/C#的文档扫描字节数组压缩方案咨询

问题:在VB/C#项目中缩减扫描文档生成的字节数组大小

当前项目未考虑扫描仪品牌/类型,单页原始图像转字节数组后大小超过3MB。不想使用付费的LEADTOOLS SDK(功能冗余、成本高,且不愿大幅修改现有代码),现有图像转字节数组的VB代码如下:

Private Shared Function ConvertImageToByteArray(ByVal imageToConvert As System.Drawing.Image, ByVal formatOfImage As Drawing.Imaging.ImageFormat) As Byte()
    Dim Ret As Byte()
    Using ms As New IO.MemoryStream()
        imageToConvert.Save(ms, formatOfImage)
        Ret = ms.ToArray()
    End Using
    Return Ret
End Function

编辑:2022/7/27 - 2:48 - 修正拼写


解决方案

以下几种方法无需引入付费SDK,仅需对现有代码做小幅修改,即可显著降低字节数组体积:

1. 改用高压缩率格式并控制质量

现有代码直接使用传入的ImageFormat,若当前用的是BMP、PNG这类无压缩/低压缩格式,换成带质量参数的JPEG或黑白专用的TIFF压缩是最直接的优化方式:

VB代码示例(JPEG带质量控制)

Private Shared Function ConvertImageToByteArray(ByVal imageToConvert As System.Drawing.Image, Optional ByVal quality As Integer = 70) As Byte()
    Dim Ret As Byte()
    Using ms As New IO.MemoryStream()
        ' 获取JPEG编码器
        Dim jpegCodec As Imaging.ImageCodecInfo = Imaging.ImageCodecInfo.GetImageEncoders().FirstOrDefault(Function(c) c.FormatID = Imaging.ImageFormat.Jpeg.Guid)
        If jpegCodec IsNot Nothing Then
            Dim encoderParams As New Imaging.EncoderParameters(1)
            ' 质量范围0-100,值越小压缩率越高(70是兼顾质量和体积的常用值)
            encoderParams.Param(0) = New Imaging.EncoderParameter(Imaging.Encoder.Quality, quality)
            imageToConvert.Save(ms, jpegCodec, encoderParams)
        Else
            ' 编码器获取失败时 fallback 默认保存
            imageToConvert.Save(ms, Imaging.ImageFormat.Jpeg)
        End If
        Ret = ms.ToArray()
    End Using
    Return Ret
End Function

TIFF黑白压缩(适合文字类扫描件)

如果是黑白文档扫描件,使用TIFF的CCITT Group 4压缩能达到极高的压缩比,且几乎不损失文字可读性:

Private Shared Function ConvertImageToByteArrayTiff(ByVal imageToConvert As System.Drawing.Image) As Byte()
    Dim Ret As Byte()
    Using ms As New IO.MemoryStream()
        Dim tiffCodec As Imaging.ImageCodecInfo = Imaging.ImageCodecInfo.GetImageEncoders().FirstOrDefault(Function(c) c.FormatID = Imaging.ImageFormat.Tiff.Guid)
        If tiffCodec IsNot Nothing Then
            Dim encoderParams As New Imaging.EncoderParameters(2)
            ' 设置压缩方式为CCITT Group 4
            encoderParams.Param(0) = New Imaging.EncoderParameter(Imaging.Encoder.Compression, Imaging.EncoderValue.CompressionCCITT4)
            ' 转换为1位黑白图像
            encoderParams.Param(1) = New Imaging.EncoderParameter(Imaging.Encoder.ColorDepth, 1L)
            imageToConvert.Save(ms, tiffCodec, encoderParams)
        Else
            imageToConvert.Save(ms, Imaging.ImageFormat.Tiff)
        End If
        Ret = ms.ToArray()
    End Using
    Return Ret
End Function

2. 降低图像分辨率

扫描文档通常默认300DPI以上,若无需高精度打印/识别,可将分辨率降至150DPI,同时按比例缩小图像尺寸,进一步减小体积:

Private Shared Function ResizeImageAndConvertToByteArray(ByVal imageToConvert As System.Drawing.Image, ByVal targetDpi As Integer = 150, ByVal quality As Integer = 70) As Byte()
    ' 计算缩放比例
    Dim scaleRatio As Double = targetDpi / imageToConvert.HorizontalResolution
    Dim newWidth As Integer = CInt(imageToConvert.Width * scaleRatio)
    Dim newHeight As Integer = CInt(imageToConvert.Height * scaleRatio)
    
    ' 创建缩小后的图像并保持目标分辨率
    Using resizedImage As New Bitmap(newWidth, newHeight)
        resizedImage.SetResolution(targetDpi, targetDpi)
        Using g As Graphics = Graphics.FromImage(resizedImage)
            ' 保证缩放后图像质量
            g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
            g.DrawImage(imageToConvert, 0, 0, newWidth, newHeight)
        End Using
        ' 调用JPEG压缩逻辑
        Return ConvertImageToByteArray(resizedImage, quality)
    End Using
End Function

3. 转换为灰度图像

文档类图像以文字为主,转换为灰度图像可减少色彩通道数量,配合压缩格式能进一步降低体积:

Private Shared Function ConvertToGrayscaleAndSave(ByVal imageToConvert As System.Drawing.Image, ByVal quality As Integer = 70) As Byte()
    Using grayBitmap As New Bitmap(imageToConvert.Width, imageToConvert.Height)
        Using g As Graphics = Graphics.FromImage(grayBitmap)
            ' 灰度转换矩阵
            Dim grayMatrix As New Imaging.ColorMatrix(New Single()() {
                New Single() {0.299F, 0.299F, 0.299F, 0, 0},
                New Single() {0.587F, 0.587F, 0.587F, 0, 0},
                New Single() {0.114F, 0.114F, 0.114F, 0, 0},
                New Single() {0, 0, 0, 1, 0},
                New Single() {0, 0, 0, 0, 1}
            })
            Dim imageAttr As New Imaging.ImageAttributes()
            imageAttr.SetColorMatrix(grayMatrix)
            ' 绘制灰度图像
            g.DrawImage(imageToConvert, New Rectangle(0, 0, imageToConvert.Width, imageToConvert.Height),
                        0, 0, imageToConvert.Width, imageToConvert.Height, GraphicsUnit.Pixel, imageAttr)
        End Using
        ' 调用压缩保存逻辑
        Return ConvertImageToByteArray(grayBitmap, quality)
    End Using
End Function

内容的提问来源于stack exchange,提问作者Jesus J. Nieves-Padilla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:24:19