c# winform 解决PictureBox 无法打印全部图片的问题
一、 问题描述
在页面使用PictureBox 加载资料图片后,点击“打印”,只能打印图片首页,较大图片则无法全部打印。
二、 原因分析
PictureBox中打印图片时没有设置继续打印相关属性,因此每次只能打印第1页。
三、解决方法
PictureBox控件增加打印全部页面属性,如果为True,表示打印全部页面;如果为False,保留原有逻辑不变。
在打印全部页面时,将控件的图片按页面大小切割,打印页面索引小于页面总数时,设置打印属性PrintPageEventArgs. HasMorePages = true继续打印,打印完成后将该属性设置为False结束打印。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.Text;
using System.Windows.Forms; namespace MyClass
{ //public enum OperationState { Default, ZoomIn, ZoomOut }; public partial class UCPictureBox : PictureBox
{
//private OperationState operationState;//处理状态
private HScrollBar hScrollBar;//水平滚动条
private VScrollBar vScrollBar;//垂直滚动条
private PrintDocument printDocument;//打印对象
private Rectangle currRect;//现在矩形对象
private Bitmap currBmp;//现在图形对象
//private int hScrollBarMidVal;//水平滚动条中间值
//private int vScrollBarMidVal;//垂直滚动条中间值
private RectangleF srcRect;
private RectangleF destRect;
private bool isMoveScrollBar;//是否移动滚动条
int currentPageIndex = 0;//当前页面
int pageCount = 0;//打印页数 /// <summary>
/// 构造函数
/// </summary>
public UCPictureBox()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); //hScrollBarMidVal = 0;
//vScrollBarMidVal = 0;
//operationState = OperationState.Default;
isMoveScrollBar = false;
srcRect = new RectangleF();
destRect = new RectangleF();
printDocument = new PrintDocument();
printDocument.PrintPage += new PrintPageEventHandler(printDocument_PrintPage); //构造水平滚动条
hScrollBar = new HScrollBar();
hScrollBar.Visible = false;
hScrollBar.Dock = DockStyle.Bottom;
hScrollBar.Scroll += new ScrollEventHandler(scrollBar_Scroll);
this.Controls.Add(hScrollBar); //构造垂直滚动条
vScrollBar = new VScrollBar();
vScrollBar.Visible = false;
vScrollBar.Dock = DockStyle.Right;
vScrollBar.Scroll +=new ScrollEventHandler(scrollBar_Scroll);
this.Controls.Add(vScrollBar);
} #region 公共属性 [Category("外观"), Description("获取或设置图片")]
public new Image Image
{
get { return base.Image; }
set
{
if (value != null)
{
base.Image = value;
currRect.Width = base.Image.Width;
currRect.Height = base.Image.Height;
hScrollBar.Value = 0;
vScrollBar.Value = 0;
displayScrollBars();
setScrollBarsValues();
Invalidate();
}
}
} //缩放比例
private int scaleSize = 1;
[Category("其它"), Description("获取或设置图片缩放比例")]
public Int32 ScaleSize
{
get { return scaleSize; }
set
{
if (value > 1 && value < 51)
{
scaleSize = value;
}
}
} //缩放倍数
private int scaleScope = 5;
[Category("其它"), Description("获取或设置图片最大缩放倍数")]
public int ScaleScope
{
get { return scaleScope; }
set
{
if (value > 1 && value < 11)
{
scaleScope = value;
}
}
} //图片边框颜色
//private Color borderColor = Color.DarkGray;
//[Category("其它"), Description("获取或设置图片边框颜色")]
//public Color BorderColor
//{
// get { return borderColor; }
// set { borderColor = value; }
//} //图片边框宽度
private int borderWidth = 5;
[Category("其它"), Description("获取或设置图片边框宽度")]
public Int32 BorderWidth
{
get { return borderWidth; }
set { borderWidth = value; }
} //打印全部页面
[Category("其它"),Description("true-打印全部页面,false-打印首页")]
public bool PrintAllPages { get; set; } #endregion #region 内部公共方法 /// <summary>
/// 从新绘制
/// </summary>
protected override void OnPaint(PaintEventArgs pe)
{
// TODO: 在此处添加自定义绘制代码
// 调用基类 OnPaint
base.OnPaint(pe); if (this.Image != null)
{
if (currBmp != null) { currBmp.Dispose(); }
currBmp = new Bitmap(currRect.Width + 2 * borderWidth, currRect.Height + 2 * borderWidth);
//绘制新图片
using (Graphics g = Graphics.FromImage(currBmp))
{
using (Pen pen = new Pen(BackColor, borderWidth))
{
g.DrawRectangle(pen, borderWidth * 0.5f, borderWidth * 0.5f,
currRect.Width + borderWidth,
currRect.Height + borderWidth);
}
g.DrawImage(this.Image, borderWidth, borderWidth, currRect.Width, currRect.Height);
} //图片绘制到控件上
pe.Graphics.Clear(BackColor);
if (hScrollBar.Visible || vScrollBar.Visible)
{//滚动条可见
drawDisplayedScrollBars(pe.Graphics);
}
else
{//滚动条不可见
float x = 0, y = 0;
isMoveScrollBar = false; //是否绘制到中心点坐标
if (this.SizeMode == PictureBoxSizeMode.CenterImage)
{
x = Math.Abs(ClientSize.Width - currBmp.Width) * 0.5f;
y = Math.Abs(ClientSize.Height - currBmp.Height) * 0.5f;
}
pe.Graphics.DrawImage(currBmp, x, y, currBmp.Width, currBmp.Height);
}
}
} /// <summary>
/// 重写控件大小发生改变事件
/// </summary>
protected override void OnClientSizeChanged(EventArgs e)
{
base.OnClientSizeChanged(e);
displayScrollBars();
setScrollBarsValues();
Invalidate();
} #endregion #region 图片打印与预览 /// <summary>
/// 打印图片
/// </summary>
public void PrintPictrue()
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument;
//added by lky 2017-11-16 修复Windows 7 x64位环境无法弹出打印对话框的问题
printDialog.UseEXDialog = true;
if (printDialog.ShowDialog() == DialogResult.OK)
{
try
{
printDocument.Print();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
} /// <summary>
/// 打印预览
/// </summary>
public void PrintPreview()
{
PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
printPreviewDialog.Document = printDocument;
try
{
printPreviewDialog.ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
} /// <summary>
/// 打印图片事件
/// </summary>
private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
if (currBmp == null)
return;
try
{
if (PrintAllPages)//added by lky 2018-1-15 打印全部页面
{
int pageWith =(int) e.PageSettings.PrintableArea.Width;
int pageHeight = (int)e.PageSettings.PrintableArea.Height;
int horizontalTimes = (int)Math.Ceiling((decimal)currBmp.Width / pageWith);//水平方向切割页数
int verticalTimes = (int)Math.Ceiling((decimal)currBmp.Height / pageHeight);//垂直方向切割页数
if (pageCount == 0)
{
pageCount = horizontalTimes * verticalTimes;//总页数
currentPageIndex = 0;
}
int horizontalCurrentPosition = (currentPageIndex % horizontalTimes);//当前打印的水平偏移页数
int verticalCurrentPosition = (int)Math.Floor((decimal)currentPageIndex / horizontalTimes);//当前打印的垂直偏移页数
int x = horizontalCurrentPosition * pageWith;//水平方向打印偏移位置
int y = verticalCurrentPosition * pageHeight;//垂直方向打印偏移位置
int leftX = (currBmp.Width - x) > 0 ? (currBmp.Width - x) : 0;//水平方向未打印尺寸
int leftY = (currBmp.Height - y) > 0 ? (currBmp.Height - y) : 0;//垂直方向未打印尺寸 Bitmap printBmp = (Bitmap)currBmp.Clone(new Rectangle(x, y, (leftX > pageWith ? pageWith : leftX),
(leftY > pageHeight ? pageHeight : leftY)), currBmp.PixelFormat); //待打印图片缓存
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed; e.Graphics.DrawImage(printBmp, 0, 0, printBmp.Width, printBmp.Height);
printBmp.Dispose();
currentPageIndex++;
e.HasMorePages = currentPageIndex < pageCount;//是否继续打印
if (!e.HasMorePages) pageCount = 0;//打印页数置为0
}
else //仅打印首页
{
Bitmap printBmp = (Bitmap)currBmp.Clone();
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
e.Graphics.DrawImage(printBmp, 0, 0, printBmp.Width, printBmp.Height);
printBmp.Dispose();
}
}
catch (Exception ex)
{
//写日志文件
LogWriter.Write(LOG_CATEGORY.WIN_UI, LOG_LEVEL.ERROR, "UCPicturBox.PrintPage" + ex.ToString());
}
} #endregion #region 图片放大、缩小、原始大小、全屏显示、旋转功能 /// <summary>
/// 放大图片
/// </summary>
public void ZoomInPicture()
{
if (this.Image != null)
{
//operationState = OperationState.ZoomIn;
double scale = 1 + (scaleSize * 0.01);
currRect.Width = Convert.ToInt32(currRect.Width * scale);
currRect.Height = currRect.Width * this.Image.Height / this.Image.Width;
if (currRect.Width < (this.Image.Width * scaleScope))
{
displayScrollBars();
setScrollBarsValues();
Invalidate();
}
}
} /// <summary>
/// 缩小图片
/// </summary>
public void ZoomOutPicture()
{
if (this.Image != null)
{
//operationState = OperationState.ZoomOut;
double scale = 1 - (scaleSize * 0.01);
currRect.Width = Convert.ToInt32(currRect.Width * scale);
currRect.Height = currRect.Width * this.Image.Height / this.Image.Width;
displayScrollBars();
setScrollBarsValues();
Invalidate();
}
} /// <summary>
/// 原始大小
/// </summary>
public void ZoomOriginalPicture()
{
if (this.Image != null)
{
//operationState = OperationState.Default;
isMoveScrollBar = false;
currRect.Width = this.Image.Width;
currRect.Height = this.Image.Height;
displayScrollBars();
setScrollBarsValues();
Invalidate();
}
} /// <summary>
/// 全屏显示
/// </summary>
public void ZoomShowAllPicture()
{
if (this.Image != null)
{
if (this.Image.Width > this.Image.Height)
{
currRect.Width = ClientSize.Width - 2 * borderWidth;
currRect.Height = currRect.Width * this.Image.Height / this.Image.Width;
if ((currRect.Height + 2 * borderWidth) > ClientSize.Height)
{
currRect.Height = ClientSize.Height - 2 * borderWidth;
currRect.Width = currRect.Height * this.Image.Width / this.Image.Height;
}
//if ((currRect.Height + 2 * borderWidth) > ClientSize.Height)
//{
// currRect.Width = ClientSize.Width - 2 * borderWidth - vScrollBar.Width;
// currRect.Height = currRect.Width * this.Image.Height / this.Image.Width;
//}
}
else
{
currRect.Height = ClientSize.Height - 2 * borderWidth;
currRect.Width = currRect.Height * this.Image.Width / this.Image.Height;
if ((currRect.Width + 2 * borderWidth) > ClientSize.Width)
{
currRect.Width = ClientSize.Width - 2 * borderWidth;
currRect.Height = currRect.Width * this.Image.Width / this.Image.Height;
}
//if ((currRect.Width + 2 * borderWidth) > ClientSize.Width)
//{
// hScrollBar.Value = 0;
// currRect.Height = ClientSize.Height - 2 * borderWidth - hScrollBar.Height;
// currRect.Width = currRect.Height * this.Image.Width / this.Image.Height;
//}
}
isMoveScrollBar = false;
displayScrollBars();
setScrollBarsValues();
Invalidate();
}
} /// <summary>
/// 旋转图片
/// </summary>
public void RotatePicture()
{
if (this.Image != null)
{
isMoveScrollBar = false;
this.Image.RotateFlip(RotateFlipType.Rotate90FlipNone);
int tempWidth = currRect.Width;
currRect.Width = currRect.Height;
currRect.Height = tempWidth;
displayScrollBars();
setScrollBarsValues();
Invalidate();
}
} /// <summary>
/// 显示水平滚动条与垂直滚动条
/// </summary>
private void displayScrollBars()
{
//是否显示水平滚动条
if ((currRect.Width + 2 * borderWidth) > ClientSize.Width)
{ hScrollBar.Visible = true; }
else
{ hScrollBar.Visible = false; } //是否显示垂直滚动条
if ((currRect.Height + 2 * borderWidth) > ClientSize.Height)
{ vScrollBar.Visible = true; }
else
{ vScrollBar.Visible = false; }
} /// <summary>
/// 设置水平滚动条与垂直滚动条值
/// </summary>
private void setScrollBarsValues()
{
//设置水平滚动条值
if (hScrollBar.Visible)
{
hScrollBar.Minimum = 0;
hScrollBar.Maximum = currRect.Width - ClientSize.Width + 2 * borderWidth;
hScrollBar.LargeChange = currRect.Width / 10;
if (vScrollBar.Visible)
{
hScrollBar.Maximum += vScrollBar.Width;
}
if (hScrollBar.LargeChange > hScrollBar.Maximum)
{
hScrollBar.LargeChange = hScrollBar.Maximum - 1;
}
hScrollBar.SmallChange = hScrollBar.LargeChange / 5;
hScrollBar.Maximum += hScrollBar.LargeChange; //绘制坐标为中心点
if (this.SizeMode == PictureBoxSizeMode.CenterImage)
{
if (hScrollBar.Value == 0 || isMoveScrollBar == false)
{
hScrollBar.Value = (hScrollBar.Maximum - hScrollBar.LargeChange) / 2;
}
}
}
else
{ hScrollBar.Value = 0; } //设置垂直滚动条值
if (vScrollBar.Visible)
{
vScrollBar.Minimum = 0;
vScrollBar.Maximum = currRect.Height - ClientSize.Height + 2 * borderWidth;
vScrollBar.LargeChange = currRect.Height / 10;
if (hScrollBar.Visible)
{
vScrollBar.Maximum += hScrollBar.Height;
}
if (vScrollBar.LargeChange > vScrollBar.Maximum)
{
vScrollBar.LargeChange = vScrollBar.Maximum - 1;
}
vScrollBar.SmallChange = vScrollBar.LargeChange / 5;
vScrollBar.Maximum += vScrollBar.LargeChange; //绘制坐标为中心点
if (this.SizeMode == PictureBoxSizeMode.CenterImage)
{
if (vScrollBar.Value == 0 || isMoveScrollBar ==false)
{
vScrollBar.Value = (vScrollBar.Maximum - vScrollBar.LargeChange) / 2;
}
}
}
else
{ vScrollBar.Value = 0; }
} /// <summary>
/// 移动水平滚动条事件
/// </summary>
private void scrollBar_Scroll(object sender, ScrollEventArgs e)
{
isMoveScrollBar = true;
using (Graphics graphics = this.CreateGraphics())
{
drawDisplayedScrollBars(graphics);
}
this.Update();
} /// <summary>
/// 从新绘制显示的滚动条
/// </summary>
private void drawDisplayedScrollBars(Graphics graphics)
{
float x = 0, y = 0; if (this.SizeMode == PictureBoxSizeMode.CenterImage)
{
x = Math.Abs(ClientSize.Width - currBmp.Width - vScrollBar.Width) * 0.5f;
y = Math.Abs(ClientSize.Height - currBmp.Height - hScrollBar.Height) * 0.5f;
}
if (hScrollBar.Visible == false)
{//水平滚动条不可见
destRect.X = x;
destRect.Y = 0;
srcRect.X = 0;
srcRect.Y = vScrollBar.Value;
}
else if (vScrollBar.Visible == false)
{//垂直滚动条不可见
destRect.X = 0;
destRect.Y = y;
srcRect.Y = 0;
srcRect.X = hScrollBar.Value;
}
else
{//两个滚动条都可见
destRect.X = 0;
destRect.Y = 0;
srcRect.X = hScrollBar.Value;
srcRect.Y = vScrollBar.Value;
}
destRect.Width = currBmp.Width;
destRect.Height = currBmp.Height;
srcRect.Width = currBmp.Width;
srcRect.Height = currBmp.Height;
graphics.DrawImage(currBmp, destRect, srcRect, GraphicsUnit.Pixel);
} #endregion
}
}
c# winform 解决PictureBox 无法打印全部图片的问题的更多相关文章
- winform下picturebox控件显示图片问题
viewData_pictureBox.SizeMode=PictureBoxSizeMode.StretchImage;图片会自动按照比例缩放来完全显示在你的PictureBox中.
- WPF和Winform中picturebox图片局部放大
原文:WPF和Winform中picturebox图片局部放大 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/artic ...
- nginx实现动态分离,解决css和js等图片加载问题
改帖专门为使用nginx,通过nginx把请求转发到web服务器再返回客户端的时候,解决css和js和图片加载不出来的问题. 如果没安装nginx,请访问一下地址进行安装 http://www.cnb ...
- AutoCAD图形打印出图片 C#
这几天搞cad二次开发,用的是C#语言,目前在网上找到的资料比较少.弄了两天,才做出怎样实现打印出图片.首先得在AutoCAD软件界面下,设置打印机的页面设置和打印机设备名称一样(以防打印不出来).即 ...
- 解决iOS中 tabBarItem设置图片(image+title切图在一起)时造成的图片向上偏移
解决iOS中 tabBarItem设置图片(image+title切图在一起)时造成的图片向上偏移 解决办法1:设置tabBarItem的imageInsets属性 代码示例: childContro ...
- 解决全站ie6下PNG图片不透明问题只要几行代码
解决全站ie6下PNG图片不透明问题只要复制下面这几行代码粘贴在你的文档最底部,需要用到的包DD_belatedPNG_0.0.8a.js自己网上下载吧 代码走起 /*在文档底部加入以下代码*/ &l ...
- DevExpress Winform 通用控件打印方法(允许可自定义边距) z
DevExpress Winform 通用控件打印方法,包括gridcontrol,treelist,pivotGridControl,ChartControl,LayoutControl...(所有 ...
- C#:使用FastReport打印带图片传参模板的实现方法
大家都知道,C#打印图片可以直接调用PrintDocument控件的PrintPage事件,通过画刷对image对象直接进行绘制.但是这种方法存在局限,例如如果打印的图片需要按纸张大小进行缩放的话,那 ...
- winform label文本转换为图片 、Picturebox+label合并转换为图片
public Form1() { InitializeComponent(); //label存入Picturebox pictureBox1.Controls.Add(label1); pictur ...
随机推荐
- redis在mac中的安装和启动
http://blog.csdn.net/chenshuai1993/article/details/51519384 http://www.jianshu.com/p/6b5eca8d908b
- PHP面向对象——三大基本特性与五大基本原则
三大特性是:封装.继承.多态 所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏. 封装是面向对象的特征之一,是对象和类概念的主要特 ...
- Oracle SQL七次提速技巧
以下SQL执行时间按序号递减. 1,动态SQL,没有绑定变量,每次执行都做硬解析操作,占用较大的共享池空间,若共享池空间不足,会导致其他SQL语句的解析信息被挤出共享池. create or repl ...
- socket编程 —— 非阻塞socket (转)---例子已上传至文件中
在上一篇文章 <socket编程——一个简单的例子> http://blog.csdn.net/wind19/archive/2011/01/21/6156339.aspx 中写了一个简单 ...
- BZOJ2384:[CEOI2014]Match
浅谈\(KMP\):https://www.cnblogs.com/AKMer/p/10438148.html 题目传送门:https://lydsy.com/JudgeOnline/problem. ...
- Centos6.8 安装MySql
启动Centos6.8 输入命令: yum install mysql mysql-server -y 等待安装完成. 启动MySQL,输入命令: /etc/init.d/mysqld s ...
- 谈谈对zynq的浅显理解
zynq并不能说是一个嵌入arm核的FPGA.从它的启动过程就可以发现,绝对是arm主导的,所以称它为以高性能FPGA为外设的双核arm或许更为合适.以下是优势: 第一个:开发环境的大集成.从hls到 ...
- Eclipse中创建新的Spring Boot项目
本文转载自:http://blog.csdn.net/clementad/article/details/51334064 简单几步,在Eclipse中创建一个新的spring Boot项目: 1.E ...
- java web 程序---登陆验证注销/重定向session_login.jsp/
思路:第一个页面是:session_login.页面,一个form表单,一个脚本,输入的名称不为空,不,则重定向 到welcome.jsp页面.否则,显示登陆失败,请输入登陆名称: 第二个页面,是we ...
- 1135 Is It A Red-Black Tree
题意:给出k个二叉搜索树的前序序列,判断该树是否为红黑树. 红黑树的定义: 结点的颜色非红即黑 根结点的颜色必须是黑色 每个叶子结点(指的是空结点,图中并没有画出来)都是黑色的 如果某个结点为红色,则 ...