C#图像处理与打印功能实现指南

Mason
Mason
发布时间:2026-10-15 | 4人浏览过
原创

本文深入探讨C#中System.Drawing命名空间的两大核心组件:Image类用于图像的处理与编辑,PrintDocument类负责文档的打印输出。文章涵盖图片属性的获取、常用操作方法(如缩放、旋转),以及如何使用PrintDocument实现带预览功能的多页文档打印流程。

图像处理基础操作

在C#桌面应用开发中,System.Drawing命名空间提供了强大的图形处理能力。Image是位图(Bitmap)和元文件(Metafile)的抽象基类,虽然不能直接实例化,但可以通过静态方法创建具体的对象实例。

第1步:初始化Image对象

目的:从文件或流中加载图像数据。

  • 入口:Image.FromFile()、Image.FromStream()或Bitmap构造函数。
  • 动作:
Image imgFromFile = Image.FromFile(@"C:\1.jpg");
Image imgFromStream = Image.FromStream(File.OpenRead(@"C:\1.jpg"));
Image imgNewBitmap = new Bitmap(@"C:\1.jpg");

完成状态:Image对象已建立并指向内存中的图像数据。

第2步:读取图像属性

目的:获取图像的基本信息,用于后续绘图或布局计算。

  • 关键参数:
  • PixelFormat:像素格式。
  • RawFormat:文件格式标识(如JPEG、PNG)。
  • Size、Width、Height:图像的分辨率尺寸。

第3步:执行图像编辑操作

目的:对图像进行视觉效果的修改,包括绘制新内容、缩放、旋转和格式转换。

3.1 绘制图像

使用Graphics对象将已有图像绘制到新的画布上:

using (Image img = new Bitmap(@"C:\1.jpg"))
{
    using (Graphics g = Graphics.FromImage(img))
    {
        // 将原图绘制到自身区域
        g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
    }
}

3.2 缩放图像

目的:生成指定尺寸的新图像副本。

Image original = new Bitmap(@"C:\1.jpg");
// 利用Size参数创建缩小一半的Bitamp
using (Image smallImage = new Bitmap(original, new Size(original.Width / 2, original.Height / 2)))
{
    // 此时smallImage即为缩放后的图像
}

3.3 生成缩略图

目的:快速生成高质量的小尺寸预览图。

Bitmap myBitmap = new Bitmap("Climber.jpg");
// 40x40为期望缩略图尺寸
Image myThumbnail = myBitmap.GetThumbnailImage(40, 40, null, IntPtr.Zero);
// DrawImage(myThumbnail, x, y)可在控件中显示

3.4 旋转与翻转

目的:调整图像的视角方向。

img.RotateFlip(RotateFlipType.Rotate180FlipY);

注意:此操作会直接在原对象上更改,建议在复制或使用前备份。

3.5 格式转换与保存

目的:改变文件编码格式并持久化。

img.Save("c:/1.jpg", ImageFormat.Jpeg);
img.Save("c:/1.gif", ImageFormat.Gif);

第4步:双倍缓冲绘制(优化)

目的:避免屏幕闪烁,提升绘图性能。

先在内存中创建空白位图(Bitmap)作为画布,在上面绘制完成后,一次性将内存图像渲染到窗体:

using (Bitmap offscreenBuffer = new Bitmap(ClientRectangle.Width, ClientRectangle.Height))
{
    using (Graphics g = Graphics.FromImage(offscreenBuffer))
    {
        g.FillRectangle(Brushes.White, ClientRectangle);
        // 在此处绘制你的图形元素...
    }
    // 最后将离屏缓存绘制到当前窗体Graphic
    e.Graphics.DrawImage(offscreenBuffer, 0, 0);
}

系统打印功能实现

C#的打印功能主要由System.Drawing.Printing命名空间下的PrintDocument类提供支持。它支持页面设置、打印预览及实际物理输出。

第1步:配置打印与预览环境

目的:搭建打印流程框架,让用户确认内容。

  • 设置打印机名称:pd.DefaultPageSettings.PrinterSettings.PrinterName = "ZDesigner GX430t";
  • 设置纸张方向:pd.DefaultPageSettings.Landscape = true;(默认为纵向)。
  • 关联事件:绑定PrintPage事件以处理单页内容的绘制。

第2步:调用打印预览

使用PrintPreviewDialog控件,它将自动根据PrintDocument生成的页面内容进行模拟预览:

PrintDocument pd = new PrintDocument();
pd.PrintPage += Pd_PrintPage;

using (PrintPreviewDialog ppd = new PrintPreviewDialog())
{
    ppd.Document = pd;
    ppd.ShowDialog(); // 阻塞等待用户关闭预览窗口
}

第3步:处理实际打印输出

预览确认后,或直接调用Print()方法发送至打印机:

pd.Print();

第4步:实现多页文本分页打印

目的:当内容超出单页容量时,自动分页。

关键机制:在PrintPage事件中,若判断当前页未满,必须将e.HasMorePages设为true。这将导致PrintPage事件再次触发,直到设为false停止循环。

操作细节:

  1. 计算总量:在BeginPrint事件中初始化全局变量(如剩余行数、总高度)。
  2. 单次绘制:在PrintPage中计算本可打印的区域(e.MarginBounds)。
  3. 条件判定:比较已打印内容与总内容。若未打印完,更新偏移量并设置e.HasMorePages = true。
private string printText;
private int currentTopOffset;
private Size textSize;

private void button1_Click(object sender, EventArgs e)
{
    printText = this.textBox1.Text;
    var pd = new PrintDocument();
    pd.BeginPrint += (s, eArgs) => { 
        textSize = Size.Empty; 
        currentTopOffset = 0; 
    };
    pd.PrintPage += Pd_PrintPage;

    using (var dlg = new PrintPreviewDialog { Document = pd })
    {
        dlg.ShowDialog();
    }
}

private void Pd_PrintPage(object sender, PrintPageEventArgs e)
{
    // 1. 测量文字总体积
    if (textSize == Size.Empty)
    {
        textSize = Size.Round(e.Graphics.MeasureString(printText, Font, e.MarginBounds.Width));
    }

    // 2. 设置裁剪区域,防止溢出边框
    e.Graphics.SetClip(e.MarginBounds);

    // 3. 绘制当前视口内容
    e.Graphics.DrawString(
        printText, 
        this.Font, 
        Brushes.Black, 
        new Rectangle(e.MarginBounds.X, e.MarginBounds.Y - currentTopOffset, textSize.Width, textSize.Height)
    );

    // 4. 检查是否还有剩余内容需要下一页打印
    if (currentTopOffset + e.MarginBounds.Height < textSize.Height)
    {
        currentTopOffset += e.MarginBounds.Height;
        e.HasMorePages = true; // 关键:触发下一次PrintPage
    }
    else
    {
        e.HasMorePages = false; // 结束打印
    }
}

以上就是C#中Image类与PrintDocument打印功能的详细内容,更多关于.NET图像处理的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表