如何用ImageMagick.NET/Ghostscript将图片居中打印至7.5×6英寸PCL页面
JPG图片在7.5×6英寸PCL页面居中打印的解决方法
问题根源分析
你现有代码的核心问题在于DPI逻辑混乱和页面尺寸/位置计算不一致:
- ImageMagick代码中先固定图片尺寸再重复缩放,导致实际尺寸偏离预期;且未正确设置画布DPI,生成的文件页面元数据不匹配。
- Ghostscript参数中
-dPDFFitPage会强制缩放PDF适配页面,可能抵消-dCenterImage的居中效果,同时PDF本身的页面尺寸可能未与目标PCL页面对齐。
方案一:仅用ImageMagick.NET直接实现(无需Ghostscript)
ImageMagick支持直接输出PCL格式,只需统一DPI逻辑、正确计算居中位置即可:
修正后的代码
using (var image = new MagickImage(inputJpgPath)) { // 统一使用目标打印DPI(推荐300,适配多数打印机) int targetDpi = 300; image.Density = new PointD(targetDpi, targetDpi); // 计算目标页面的像素尺寸:7.5英寸 × DPI,6英寸 × DPI int pageWidth = (int)(7.5 * targetDpi); int pageHeight = (int)(6 * targetDpi); // 按比例缩放图片,确保不超出页面边界 image.Resize(new MagickGeometry(pageWidth, pageHeight) { IgnoreAspectRatio = false, // 保持图片比例 FillArea = false // 只缩小不放大(可选,按需调整) }); // 创建对应尺寸的白色画布,并设置DPI var canvas = new MagickImage(new MagickColor(Color.White), pageWidth, pageHeight); canvas.Density = new PointD(targetDpi, targetDpi); // 计算居中位置 int xPos = (pageWidth - image.Width) / 2; int yPos = (pageHeight - image.Height) / 2; // 确保位置非负(图片大于页面时贴边) xPos = Math.Max(xPos, 0); yPos = Math.Max(yPos, 0); // 将图片合成到画布居中位置 canvas.Composite(image, xPos, yPos, CompositeOperator.Over); // 直接输出为PCL文件 canvas.Format = MagickFormat.Pcl; canvas.Write(outputPclPath); }
关键调整点
- 全程使用统一DPI(如300),避免多次缩放导致的尺寸偏差。
- 用
MagickGeometry按比例缩放图片,保证不失真且不超出页面。 - 明确设置画布的DPI,确保打印时页面尺寸与预期一致。
- 直接输出PCL,跳过PDF转换环节,减少中间误差。
方案二:结合ImageMagick.NET + Ghostscript(适合需保留PDF中间件的场景)
如果必须通过PDF中转,需先让ImageMagick生成页面尺寸严格为7.5×6英寸且图片居中的PDF,再调整Ghostscript参数实现居中:
步骤1:修正ImageMagick生成PDF的代码
using (var image = new MagickImage(inputJpgPath)) { int targetDpi = 300; image.Density = new PointD(targetDpi, targetDpi); // 计算PDF页面的像素尺寸(7.5×6英寸) int pageWidth = (int)(7.5 * targetDpi); int pageHeight = (int)(6 * targetDpi); // 按比例缩放图片 image.Resize(new MagickGeometry(pageWidth, pageHeight) { IgnoreAspectRatio = false }); // 创建画布并合成图片到居中位置 var canvas = new MagickImage(new MagickColor(Color.White), pageWidth, pageHeight); canvas.Density = new PointD(targetDpi, targetDpi); int xPos = (pageWidth - image.Width) / 2; int yPos = (pageHeight - image.Height) / 2; canvas.Composite(image, xPos, yPos, CompositeOperator.Over); // 输出PDF,确保页面尺寸元数据与目标一致 canvas.Format = MagickFormat.Pdf; canvas.Write(inputPdfPath); }
步骤2:调整Ghostscript参数
移除-dPDFFitPage(因为PDF页面已和目标PCL页面尺寸一致,无需缩放),确保-dCenterImage生效:
try { int widthInPoints = (int)(7.5 * 72); // 7.5英寸转PostScript点(1英寸=72点) int heightInPoints = (int)(6 * 72); int dpi = 300; // 修正后的Ghostscript参数 string gsArguments = $"-dNOPAUSE -dBATCH -dCenterImage -sDEVICE=pxlcolor -r{dpi} " + $"-dDEVICEWIDTHPOINTS={widthInPoints} " + $"-dDEVICEHEIGHTPOINTS={heightInPoints} " + $"-sOutputFile=\"{outputPclPath}\" \"{inputPdfPath}\""; ProcessStartInfo processInfo = new ProcessStartInfo { FileName = @"C:\Program Files (x86)\gs\gs10.03.1\bin\gswin32C.exe", Arguments = gsArguments, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true, }; using (Process process = Process.Start(processInfo)) { process.WaitForExit(); } } catch (Exception ex) { // 添加异常处理逻辑 }
关键调整点
- PDF页面尺寸与PCL目标页面完全一致,避免Ghostscript强制缩放。
- 移除
-dPDFFitPage和-dCenterPages(后者针对多页PDF),确保-dCenterImage单独生效。
内容的提问来源于stack exchange,提问作者subha
相关产品推荐
相关产品推荐

