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

C#实现无质量损失缩放图片并适配标签打印的技术问询

问题描述

作为嵌入式C开发者,接手C#项目需求为给PNG图片添加条码并打印,遇到以下问题:

  • 高分辨率图片直接打印时尺寸过大,会覆盖打印机的多标签布局(打印机为2行7列共14个标签)
  • 对图片缩放后尺寸适配,但质量骤降,条码无法被识别
现有代码
static Bitmap ScaleImage(Bitmap bmp, int maxWidth, int maxHeight)
{
    var ratioX = (double)maxWidth / bmp.Width;
    var ratioY = (double)maxHeight / bmp.Height;
    var ratio = Math.Min(ratioX, ratioY);

    var newWidth = (int)(bmp.Width * ratio);
    var newHeight = (int)(bmp.Height * ratio);

    var newImage = new Bitmap(newWidth, newHeight);

    using (var graphics = Graphics.FromImage(newImage))
        graphics.DrawImage(bmp, 0, 0, newWidth, newHeight);

    return newImage;
}

private void button1_Click(object sender, EventArgs e)
{
    var image = new Bitmap("C:\\Users\\gilani\\Desktop\\BarCodeCreator\\sad2.bmp");
    pictureBox1.Image = ScaleImage(image, 100, 80); 
}
private void button2_Click(object sender, EventArgs e)
{
    PrintDialog print = new PrintDialog();
    PrintDocument doc = new PrintDocument();
    doc.PrintPage += Doc_PrintPage;
    print.Document = doc;

    if (print.ShowDialog(this) == DialogResult.OK)
    {
        doc.Print();
    }
}

private void Doc_PrintPage(object sender, PrintPageEventArgs e)
{
    int start_right = 32;
    int start_Top = 0;
    Bitmap bitmp = new Bitmap(pictureBox1.Image), pictureBox1.Image.Height));
    e.Graphics.DrawImage(bitmp, start_right, start_Top);
    bitmp.Dispose();
}
代码问题分析
  1. 缩放方法ScaleImage未启用高质量渲染参数,默认缩放会丢失条码细节
  2. 打印阶段使用PictureBox中已缩放的图片,导致二次质量损失
  3. Doc_PrintPage存在语法错误,且未针对打印设备的分辨率做适配
解决方案

方案1:打印时直接缩放原图(最优)

避免提前缩放图片,在打印阶段直接对原图进行高质量缩放,适配单标签尺寸,彻底保留原图细节。

// 单标签目标打印尺寸(单位:百分之一英寸,PrintDocument默认单位)
// 示例:30mm×20mm转换为百分之一英寸约为118×79,可根据实际标签调整
private int labelWidth = 118;
private int labelHeight = 79;

private void Doc_PrintPage(object sender, PrintPageEventArgs e)
{
    // 加载原始高清图片
    using (Bitmap originalImage = new Bitmap(@"C:\Users\gilani\Desktop\BarCodeCreator\sad2.bmp"))
    {
        // 设置高质量渲染参数,保留条码细节
        e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
        e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

        // 计算等比例缩放系数
        float ratioX = (float)labelWidth / originalImage.Width;
        float ratioY = (float)labelHeight / originalImage.Height;
        float scaleRatio = Math.Min(ratioX, ratioY);

        int drawWidth = (int)(originalImage.Width * scaleRatio);
        int drawHeight = (int)(originalImage.Height * scaleRatio);

        // 指定绘制位置(沿用原代码的起始坐标)
        int startX = 32;
        int startY = 0;

        // 直接绘制缩放后的原图到打印画布
        e.Graphics.DrawImage(originalImage, startX, startY, drawWidth, drawHeight);
    }
}

方案2:优化预览缩放方法(若需提前预览)

如果必须在PictureBox中展示预览,需优化缩放方法的渲染质量,减少细节丢失:

static Bitmap ScaleImage(Bitmap bmp, int maxWidth, int maxHeight)
{
    var ratioX = (double)maxWidth / bmp.Width;
    var ratioY = (double)maxHeight / bmp.Height;
    var ratio = Math.Min(ratioX, ratioY);

    var newWidth = (int)(bmp.Width * ratio);
    var newHeight = (int)(bmp.Height * ratio);

    var newImage = new Bitmap(newWidth, newHeight);
    // 继承原图分辨率,避免分辨率丢失
    newImage.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);

    using (var graphics = Graphics.FromImage(newImage))
    {
        // 开启高质量渲染
        graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
        graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        
        graphics.Clear(Color.White);
        graphics.DrawImage(bmp, 0, 0, newWidth, newHeight);
    }

    return newImage;
}

注意:即使优化预览缩放,打印时仍建议直接使用原图,避免预览缩放的二次质量损失。

关键注意事项
  • 不要提前缩放并存储图片:提前缩放会不可逆丢失像素信息,尽量在打印阶段直接处理原图
  • 匹配打印机DPI:条码打印机常见DPI为203或300,需确保缩放后的像素数对应实际标签物理尺寸,避免打印偏差
  • 条码最小尺寸限制:条码模块宽度需满足识别阈值(如Code 128最小模块宽度不低于0.1mm),缩放时需保证该参数达标

内容的提问来源于stack exchange,提问作者S2G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:26:36