C#将所有可滚动面板保存为图像
Posted
技术标签:
【中文标题】C#将所有可滚动面板保存为图像【英文标题】:C# Save all of scrollable Panel as Image 【发布时间】:2011-05-14 12:40:55 【问题描述】:我正在尝试将所有面板保存为 JPG,我已经问过这个问题,但答案不是我想要的。问题是面板有一个滚动条(没有足够的空间容纳所有元素),但它不打印面板底部的内容,只打印可见元素。
public void DrawControl(Control control,Bitmap bitmap)
control.DrawToBitmap(bitmap,control.Bounds);
foreach (Control childControl in control.Controls)
DrawControl(childControl,bitmap);
public void SaveBitmap()
Bitmap bmp = new Bitmap(this.panel1.Width, this.panel.Height);
this.panel.DrawToBitmap(bmp, new Rectangle(0, 0, this.panel.Width, this.panel.Height));
foreach (Control control in panel1.Controls)
DrawControl(control, bmp);
bmp.Save("d:\\panel.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
【问题讨论】:
【参考方案1】:您可以滚动面板并获取每个滚动内容的位图,然后合并位图部分?
public void SaveBitmap(System.Windows.Forms.Panel CtrlToSave, string fileName)
Point oldPosition = new Point(this.HorizontalScroll.Value, this.VerticalScroll.Value);
CtrlToSave.PerformLayout();
ComposedImage ci = new ComposedImage(new Size(CtrlToSave.DisplayRectangle.Width, CtrlToSave.DisplayRectangle.Height));
int visibleWidth = CtrlToSave.Width - (CtrlToSave.VerticalScroll.Visible ? SystemInformation.VerticalScrollBarWidth : 0);
int visibleHeightBuffer = CtrlToSave.Height - (CtrlToSave.HorizontalScroll.Visible ? SystemInformation.HorizontalScrollBarHeight : 0);
//int Iteration = 0;
for (int x = CtrlToSave.DisplayRectangle.Width-visibleWidth; x >= 0 ; x -= visibleWidth)
int visibleHeight = visibleHeightBuffer;
for (int y = CtrlToSave.DisplayRectangle.Height-visibleHeight; y >= 0 ; y -= visibleHeight)
CtrlToSave.HorizontalScroll.Value = x;
CtrlToSave.VerticalScroll.Value = y;
CtrlToSave.PerformLayout();
Bitmap bmp = new Bitmap(visibleWidth, visibleHeight);
CtrlToSave.DrawToBitmap(bmp, new Rectangle(0, 0, visibleWidth, visibleHeight));
ci.images.Add(new ImagePart(new Point(x,y),bmp));
///Show image parts
//using (Graphics grD = Graphics.FromImage(bmp))
//
// Iteration++;
// grD.DrawRectangle(Pens.Blue,new Rectangle(0,0,bmp.Width-1,bmp.Height-1));
//grD.DrawString("x:"+x+",y:"+y+",W:"+visibleWidth+",H:"+visibleHeight + " I:" + Iteration,new Font("Segoe UI",9f),Brushes.Red,new Point(2,2));
//
if (y - visibleHeight < (CtrlToSave.DisplayRectangle.Height % visibleHeight))
visibleHeight = CtrlToSave.DisplayRectangle.Height % visibleHeight;
if (visibleHeight == 0)
break;
if (x - visibleWidth < (CtrlToSave.DisplayRectangle.Width % visibleWidth))
visibleWidth = CtrlToSave.DisplayRectangle.Width % visibleWidth;
if (visibleWidth == 0)
break;
Bitmap img = ci.composeImage();
img.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
CtrlToSave.HorizontalScroll.Value = oldPosition.X;
CtrlToSave.VerticalScroll.Value = oldPosition.Y;
public class ComposedImage
public Size dimensions;
public List<ImagePart> images;
public ComposedImage(Size dimensions)
this.dimensions = dimensions;
this.images = new List<ImagePart>();
public ComposedImage(Size dimensions, List<ImagePart> images)
this.dimensions = dimensions;
this.images = images;
public Bitmap composeImage()
if (dimensions == null || images == null)
return null;
Bitmap fullbmp = new Bitmap(dimensions.Width, dimensions.Height);
using (Graphics grD = Graphics.FromImage(fullbmp))
foreach (ImagePart bmp in images)
grD.DrawImage(bmp.image, bmp.location.X, bmp.location.Y);
return fullbmp;
public class ImagePart
public Point location;
public Bitmap image;
public ImagePart(Point location, Bitmap image)
this.location = location;
this.image = image;
【讨论】:
这对我来说很有效,我的用例有一个小模组。【参考方案2】:位图当然太小了,让它和panel.DisplayRectangle一样大。如果您不想在图像中获取滚动条,请不要绘制面板。
【讨论】:
【参考方案3】:我意识到这是一个旧线程,但我找到了一种更简单的方法来将单个面板的内容保存为图像。这适用于单个面板,目前我的一份报告使用这种方法打印到 1560 x 6043。
private void button2_Click(object sender, EventArgs e)
panel1.AutoSize = true;
panel1.Refresh();
using (Bitmap bmp = new Bitmap(panel1.Width, panel1.Height))
panel1.DrawToBitmap(bmp, new Rectangle(Point.Empty, bmp.Size));
string fileName = "Full_Domain_Report_" + DateTime.Now.ToString("yyyy-MM-dd_HH_mm_ss") + ".png";
bmp.Save(@"C:\temp\" + fileName, ImageFormat.Png); // make sure path exists!
panel1.AutoSize = false;
panel1.Refresh();
【讨论】:
问题要求滚动面板,但它只保存可见区域。以上是关于C#将所有可滚动面板保存为图像的主要内容,如果未能解决你的问题,请参考以下文章