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生成的缩略图出现图像部分被裁切,且未保留原图像分辨率。
问题原因
- 图像裁切:
Image.Thumbnail默认使用Enums.Interesting.Centre裁切模式,会将图像缩放到覆盖指定的宽高尺寸,超出部分自动裁切,导致图像内容丢失。 - 分辨率丢失:
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
相关产品推荐
相关产品推荐

