C # Сохранить всю прокручиваемую панель как изображение - PullRequest
2 голосов
/ 14 мая 2011

Я пытаюсь сохранить всю панель в 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);
}

Ответы [ 3 ]

1 голос
/ 21 января 2015

Вы можете прокрутить панель и получить растровое изображение каждого прокручиваемого содержимого, а затем объединить части растрового изображения?

    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;
    }
}
1 голос
/ 14 мая 2011

Растровое изображение слишком маленькое, конечно, сделайте его размером с panel.DisplayRectangle Не рисуйте панель, если вы не хотите использовать полосы прокрутки на изображении.

0 голосов
/ 09 февраля 2018

Я понимаю, что это старая тема, но я нашел гораздо более простой способ сохранить содержимое одной панели в виде изображения. Это будет работать для одной панели, в настоящее время один из моих отчетов печатается с разрешением 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();
}
...