C# 生成 JPG 缩略图字节数组函数

Chloe
Chloe
发布时间:2026-10-15| 3人浏览过
原创

在 C# 开发中,有时需要直接将图片处理为内存中的字节流以便传输或存入数据库,而非先写入磁盘文件。本教程介绍如何使用 System.Drawing 命名空间编写一个高效、灵活的静态方法,通过指定路径、目标尺寸、压缩质量及缩放模式,快速生成 JPG 格式的缩略图字节数组。

功能目标与准备条件

该方法的核心目标是接收一张原始图片的路径,经过图像处理和压缩后,输出一个 byte[] 数组。为了实现高质量的视觉效果和灵活的控制,我们需要引入以下关键要素:

  • 依赖库:需要引用 System.Drawing 和 System.Drawing.Imaging 命名空间。
  • 缩放模式:支持四种常见的图像处理需求:
    • HW:强制拉伸至指定宽和高,可能导致图像变形。
    • W:保持原图纵横比,仅按指定宽度计算高度。
    • H:保持原图纵横比,仅按指定高度计算宽度。
    • Cut:在保持纵横比的前提下,裁切多余部分以适应目标尺寸(不变形)。
  • 编码参数:使用 Encoder.Quality 控制 JPEG 压缩质量(0-100)。

第 1 步:定义核心方法签名

首先创建一个静态类或将其添加到现有工具类中。方法需接收原始图片路径、JPEG 质量系数、目标宽高以及操作模式。

public static byte[] MakeJPGThumbnailBytes(
    string originalImagePath, 
    long quality, 
    int width, 
    int height, 
    string mode)
{
    // 待实现逻辑
}

第 2 步:加载原图与初始化画布

使用 Image.FromFile 加载源图像,获取其原始宽高(ow, oh)。同时创建用于绘制的位图和图形上下文,并设置高质量的渲染属性以消除锯齿。

Image originalImage = Image.FromFile(originalImagePath);
MemoryStream s = new MemoryStream();
int towidth = width;
int toheight = height;

int x = 0;
int y = 0;
int ow = originalImage.Width;
int oh = originalImage.Height;

// 创建目标尺寸的 Bitmap 和 Graphics
Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
Graphics g = System.Drawing.Graphics.FromImage(bitmap);

// 设置高级绘图质量
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.Clear(Color.Transparent);

第 3 步:计算裁剪区域与绘制

根据选择的 mode 计算最终图像的源坐标 (x, y) 和源尺寸 (ow, oh),然后使用 DrawImage 将原图的特定部分绘制到新的画布上。

switch (mode)
{
    case "HW": // 指定高宽缩放(可能变形)
        break; // towidth/toheight 保持不变

    case "W": // 指定宽,高按比例
        toheight = (originalImage.Height * width) / originalImage.Width;
        break;

    case "H": // 指定高,宽按比例
        towidth = (originalImage.Width * height) / originalImage.Height;
        break;

    case "Cut": // 指定高宽裁减(不变形)
        // 判断原图长宽比是否大于目标长宽比
        if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
        {
            oh = originalImage.Height;
            ow = (originalImage.Height * towidth) / toheight;
            y = 0;
            x = (originalImage.Width - ow) / 2;
        }
        else
        {
            ow = originalImage.Width;
            oh = (originalImage.Width * height) / towidth;
            x = 0;
            y = (originalImage.Height - oh) / 2;
        }
        break;
    default:
        break;
}

// 执行绘制
// 参数说明: 目标位置(0,0,towidth,toheight), 源矩形(x,y,ow,oh)
g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
            new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel);

第 4 步:配置编码器并保存为字节数组

JPEG 保存需要特定的 ImageCodecInfo。我们通过遍历系统注册的编码器找到对应 MIME 类型的编码器,并设置质量参数。最后将图像保存到 MemoryStream 并返回缓冲区。

try
{
    EncoderParameters eps = new EncoderParameters(1);
    EncoderParameter ep = new EncoderParameter(Encoder.Quality, quality);
    eps.Param[0] = ep;

    // 获取 JPEG 编码器信息
    ImageCodecInfo codecInfo = GetCodecInfo("image/jpeg");
    if (codecInfo == null) throw new Exception("未找到 JPEG 编码器");

    bitmap.Save(s, codecInfo, eps);
    return s.GetBuffer();
}
catch (System.Exception e)
{
    throw e;
}
finally
{
    // 务必释放所有非托管资源
    originalImage.Dispose();
    bitmap.Dispose();
    s.Dispose();
    g.Dispose();
}

辅助方法:获取 ImageCodecInfo

为了查找正确的图像编码器(如 JPG),需要遍历 ImageCodecInfo.GetImageEncoders() 并匹配 MIME 类型。

private static ImageCodecInfo GetCodecInfo(string mimeType)
{
    ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
    foreach (ImageCodecInfo ici in CodecInfo)
    {
        if (ici.MimeType == mimeType) return ici;
    }
    return null;
}

完成判断与注意事项

调用此方法后,您将得到一个包含 JPG 压缩数据的字节数组。使用时请注意以下几点:

  1. 资源释放:代码已在 finally 块中确保了 Image、Bitmap、Graphics 和 MemoryStream 的释放,防止内存泄漏。
  2. 线程安全:System.Drawing 在某些 Windows 服务或非 UI 线程环境中可能存在稳定性问题,建议仅在单线程或确保环境支持的场景下使用。
  3. 空指针风险:若图片不存在或损坏,Image.FromFile 会抛出异常;若未找到 JPEG 编码器,GetCodecInfo 返回 null 会导致后续保存失败,实际项目中建议增加判空逻辑。

以上就是基于 C# GDI+ 实现 JPG 缩略图字节生成的详细内容,更多关于 C# 图像处理及性能优化的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。