这篇文章把magick.net常用的几个功能贴出来,包括上一篇文章的核心“像素放大”,以及格式转换、水印、合成这些日常高频操作。
一、magick.net是什么?
imagemagick本身是c写的,跨平台命令行工具,功能极其强大——支持100多种图像格式,缩放、旋转、裁剪、滤镜、合成、pdf转换全都能干。
magick.net是它的.net封装,nuget装上就能用,不需要在服务器上额外安装imagemagick。
安装:
install-package magick.net-q16-anycpu
q16表示每个通道16位(颜色精度更高),anycpu表示跨平台。如果只需要8位精度,可以用magick.net-q8-anycpu。
二、像素放大:一行代码的事
上一篇文章用几十行代码实现了最近邻和双线性插值。magick.net里,缩放就一行:
using imagemagick;
public void resizeimage(string inputpath, string outputpath, int width, int height)
{
using (var image = new magickimage(inputpath))
{
// 缩放到指定尺寸,自动保持宽高比
image.resize(width, height);
image.write(outputpath);
}
}
如果高度传0,magick.net会自动根据宽高比计算。
强制拉伸(忽略宽高比) :
var size = new magickgeometry(width, height); size.ignoreaspectratio = true; image.resize(size);
插值算法怎么选:magick.net默认用lanczos滤波算法,质量很高。如果追求速度、不介意画质,可以改成最近邻:
image.resize(width, height, filtertype.point); // point = 最近邻
其他可选:filtertype.box(邻域平均)、filtertype.mitchell(双三次)、filtertype.lanczos(高质量默认)。
批量处理:循环读文件,逐个resize,没什么特别的。但注意用完及时dispose,using包好就行。
三、格式转换:100多种格式随便转
工业相机出来的可能是raw、bayer、tiff,但最终存图常用jpeg或png。magick.net支持100多种格式互转。
public void convertformat(string inputpath, string outputpath)
{
using (var image = new magickimage(inputpath))
{
// 根据输出文件扩展名自动判断格式
image.write(outputpath);
}
}
想指定格式也行:
image.format = magickformat.png; image.write(outputpath);
jpeg质量控制:
image.quality = 90; // 0-100,越高文件越大质量越好
image.write("output.jpg");
质量值越高保留细节越多,文件也越大。工业存档一般用95,预览用80就够了。
四、添加水印:文字和图片都能加
文字水印:
public void addtextwatermark(string inputpath, string outputpath, string text)
{
using (var image = new magickimage(inputpath))
{
// 创建一个绘图对象
using (var drawing = new drawables())
{
// 设置字体、大小、颜色、位置
drawing.fontpointsize(48);
drawing.fillcolor(magickcolors.white);
drawing.textalignment(textalignment.center);
// 在图片中央偏下位置写字
drawing.text(image.width / 2, image.height - 50, text);
drawing.draw(image);
}
image.write(outputpath);
}
}
图片水印(logo叠加) :
public void addimagewatermark(string backgroundpath, string watermarkpath, string outputpath)
{
using (var background = new magickimage(backgroundpath))
using (var watermark = new magickimage(watermarkpath))
{
// 把水印缩放到合适大小(比如原图的1/4)
watermark.resize(background.width / 4, 0);
// 合成:把水印放在右下角
int x = background.width - watermark.width - 20;
int y = background.height - watermark.height - 20;
background.composite(watermark, x, y, compositeoperator.over);
background.write(outputpath);
}
}
compositeoperator.over表示水印盖在背景图上面。还可以用multiply(变暗)、screen(变亮)等不同的合成模式。
五、图像合成:两张拼一张
左右拼接:
public void mergehorizontal(string leftpath, string rightpath, string outputpath)
{
using (var left = new magickimage(leftpath))
using (var right = new magickimage(rightpath))
{
// 先创建一个空白画布,宽度=两张宽度之和,高度取最大值
int totalwidth = left.width + right.width;
int maxheight = math.max(left.height, right.height);
using (var result = new magickimage(magickcolors.white, totalwidth, maxheight))
{
// 把左图贴上去
result.composite(left, 0, 0, compositeoperator.over);
// 把右图贴在左图右边
result.composite(right, left.width, 0, compositeoperator.over);
result.write(outputpath);
}
}
}
上下拼接逻辑一样,y坐标累加就行。
多张图片合成gif动画:
public void creategif(string[] imagepaths, string outputpath)
{
using (var collection = new magickimagecollection())
{
foreach (var path in imagepaths)
{
collection.read(path);
}
// 每帧延迟100ms(单位是1/100秒)
collection.animationdelay = 10; // 10 = 100ms
collection.write(outputpath);
}
}
六、图像信息读取
有时候需要先看看图片尺寸、格式、颜色空间,再决定怎么处理:
public void getimageinfo(string path)
{
using (var image = new magickimage(path))
{
console.writeline($"宽: {image.width}, 高: {image.height}");
console.writeline($"格式: {image.format}");
console.writeline($"颜色空间: {image.colorspace}");
console.writeline($"文件大小: {image.filesize} bytes");
}
}
七、性能优化建议
1. 及时释放资源
magickimage和magickimagecollection都实现了idisposable,务必用using包起来。
2. 设置内存限制
处理超大图像时(比如工业相机出来的几十mb tiff),可以限制内存使用防止oom:
magicknet.setmemorylimit(1024 * 1024 * 1024); // 限制1gb
3. 处理pdf/eps需要ghostscript
如果涉及到pdf转图片或eps转png,需要额外安装ghostscript,64位magick.net配64位ghostscript。
4. 批量处理用parallel
处理大量图片时,可以用parallel.foreach并行处理,但注意magickimage不是线程安全的,每个线程独立创建自己的实例。
八、什么时候用magick.net,什么时候自己写
| 场景 | 推荐方案 |
|---|---|
| 偶尔处理几张图、功能单一 | 自己写(依赖少) |
| 高频采集实时处理(100fps+) | 自己写 + arraypool + span(零gc) |
| 功能多样(缩放+格式转换+水印+合成) | magick.net |
| 需要处理gif动画、pdf、eps等特殊格式 | magick.net |
| 跨平台部署(linux工控机) | magick.net(.net core原生支持) |
magick.net适合非实时或准实时场景——比如保存前的格式转换、生成缩略图、添加水印、合成报告图。功能全、代码少、质量高,那点性能开销在非实时场景下完全可以接受。
九、总结
magick.net把imagemagick上百种图像处理功能封装成了简洁的c# api。像素放大、格式转换、水印、合成,全都能用几行代码搞定。
把之前自己写的插值算法换成magick.net之后,代码量从几百行缩到了几十行,还顺便支持了彩色 图、png透明通道、jpeg质量控制这些之前不支持的功能。
如果项目里图像处理需求越来越杂,可以考虑换magick.net。nuget装完就能用,学习曲线比想象中平缓得多。
小提示:nuget上magick.net-q16-anycpu和magick.net-q8-anycpu的区别是颜色精度。工业场景一般8位够用(q8),文件更小;做图像算法研究或者需要保留更多色彩细节,用q16。
以上就是c#使用imagemagick实现像素放大水印转换等多种功能的详细内容,更多关于c# imagemagick像素放大水印转换的资料请关注代码网其它相关文章!
发表评论