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

NetVips Thumbnail生成缩略图未保留分辨率或存在图像裁切问题

NetVips生成缩略图:分辨率丢失/图像裁切问题修复

问题场景

我正在使用NetVips生成指定尺寸的图像:

  • 原图:原图
  • 生成后的结果图:生成后的结果图

当前实现代码:

public static void GetThumbNail(
    string sourcePath,
    string targetPath,
    int width,
    int height,
    int R = 255,
    int G = 255,
    int B = 255)
{
    if (targetPath == null)
        targetPath = Path.Combine(Path.GetDirectoryName(sourcePath), $"{Path.GetFileNameWithoutExtension(sourcePath)}_Thumb{Path.GetExtension(sourcePath)}");
    Image main = Image.Black(width, height, 3);
    main = main + new[] { R, G, B };
    Image watermark = Image.Thumbnail(sourcePath, width, height);
    int top = (main.Height - watermark.Height) / 2;
    int left = (main.Width - watermark.Width) / 2;
    // extract related area from main image
    var baseImage = main.Crop(left, top, watermark.Width, watermark.Height);
    // composite the two areas using the PDF "over" mode
    var composite = baseImage.Composite(watermark, Enums.BlendMode.Over);
    // the result will have an alpha, and our base image does not..we must flatten
    // out the alpha before we can insert it back into a plain RGB JPG image
    composite = composite.Flatten();
    // insert composite back in to main image on related area
    var combined = main.Insert(composite, left, top);
    combined.WriteToFile(targetPath);
}

遇到的问题:NetVips Thumbnail生成的缩略图出现图像部分被裁切,且未保留原图像分辨率。

问题原因

  1. 图像裁切:Image.Thumbnail默认使用Enums.Interesting.Centre裁切模式,会将图像缩放到覆盖指定的宽高尺寸,超出部分自动裁切,导致图像内容丢失。
  2. 分辨率丢失:Thumbnail方法默认不会保留原图像的DPI(分辨率)元数据,写入文件时会使用NetVips的默认值。

修复方案

修改代码,调整Thumbnail的裁切模式,并保留原图像的分辨率信息:

public static void GetThumbNail(
    string sourcePath,
    string targetPath,
    int width,
    int height,
    int R = 255,
    int G = 255,
    int B = 255)
{
    if (targetPath == null)
        targetPath = Path.Combine(Path.GetDirectoryName(sourcePath), $"{Path.GetFileNameWithoutExtension(sourcePath)}_Thumb{Path.GetExtension(sourcePath)}");

    // 创建指定尺寸的纯色背景图
    Image background = Image.Black(width, height, 3) + new[] { R, G, B };

    // 读取原图,获取分辨率信息
    using var originalImage = Image.NewFromFile(sourcePath);
    var xRes = originalImage.XResolution;
    var yRes = originalImage.YResolution;

    // 生成缩略图:设置crop为None,按比例缩放不裁切
    Image thumbnail = Image.Thumbnail(sourcePath, width, height, crop: Enums.Interesting.None);

    // 计算居中位置
    int top = (background.Height - thumbnail.Height) / 2;
    int left = (background.Width - thumbnail.Width) / 2;

    // 将缩略图插入背景图的居中位置
    var result = background.Insert(thumbnail, left, top);

    // 写入文件时保留原分辨率
    result.WriteToFile(targetPath, new Dictionary<string, object>
    {
        ["xres"] = xRes,
        ["yres"] = yRes
    });
}

关键修改点

  • 给Image.Thumbnail添加crop: Enums.Interesting.None参数,让图像按原比例缩放到指定尺寸内,不会裁切内容。
  • 读取原图的XResolution和YResolution,写入文件时通过参数传递,保留分辨率信息。
  • 简化逻辑:直接将缩略图插入背景图,省略不必要的Crop、Composite、Flatten步骤,因为背景是纯色,插入操作足够完成需求。

内容的提问来源于stack exchange,提问作者Juan Pablo Gomez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 11:23:19