Click here to Skip to main content
15,886,788 members
Articles / Programming Languages / C#

Capturing Web Type Content to a Single Image

Rate me:
Please Sign up or sign in to vote.
4.33/5 (2 votes)
22 Nov 2006CPOL4 min read 44.1K   194   18  
An article on how to grab Web type content and capture an image to a single file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Diagnostics;

namespace Finkenzeller.XML_Tool
{
    public partial class Main : Form
    {
        private int sourceIndex;
        private int targetIndex;

        public Main()
        {
            InitializeComponent();
            webBrowser1.AllowWebBrowserDrop = false;
        }

        private void Main_Load(object sender, EventArgs e)
        {
            // Hide the result panel
            this.Size = this.MinimumSize;
            statusStrip1.Visible = true;

            // I'm using a custom control based on the ComboBox to hold the file names
            // as I prefer the look of this to a TextBox control
            sourceList.Items.Add("Browse...");
            targetList.Items.Add("C:\\Temp\\dir.xml");
            targetList.Items.Add("Browse...");
            targetList.SelectedIndex = 0;
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            if (startButton.Text == "Start")
            {
                startButton.Text = "Stop";
                saveButton.Visible = false;
                toolStripProgressBar1.Value = 0;
                toolStripProgressBar1.Visible = true;
                toolStripStatusLabel1.Text = "Working...";
                if (this.Size == this.MinimumSize)
                {
                    this.Height = 600;
                    this.Width = 800;
                }
                this.backgroundWorker1.RunWorkerAsync();
            }
            else
            {
                startButton.Enabled = false;
                this.backgroundWorker1.CancelAsync();
                toolStripStatusLabel1.Text = "Stopping...";
            }
        }

        /// <summary>
        /// Update the source directory BetterComboBox with user changes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sourceList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if ((string)sourceList.SelectedItem == "Browse...")
            {
                FileInfo currentDirectory = new FileInfo(sourceList.Items[sourceIndex].ToString());
                folderBrowserDialog1.SelectedPath = currentDirectory.DirectoryName;
                folderBrowserDialog1.ShowNewFolderButton = false;
                if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
                {
                    sourceList.Items.Insert(0, folderBrowserDialog1.SelectedPath);
                    sourceList.SelectedIndex = 0;
                }
                else
                {
                    sourceList.SelectedIndex = sourceIndex;
                }
            }
            sourceIndex = sourceList.SelectedIndex;
        }

        /// <summary>
        /// Update the output file BetterComboBox with user changes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void targetList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if ((String)targetList.SelectedItem == "Browse...")
            {
                FileInfo currentDirectory = new FileInfo(targetList.Items[targetIndex].ToString());
                saveFileDialog1.InitialDirectory = currentDirectory.DirectoryName;
                saveFileDialog1.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    targetList.Items.Insert(0, saveFileDialog1.FileName);
                    targetList.SelectedIndex = 0;
                }
                else
                {
                    targetList.SelectedIndex = targetIndex;
                }
            }
            targetIndex = targetList.SelectedIndex;
        }

        /// <summary>
        /// Generates the XmlDocument
        /// </summary>
        /// <param name="source"></param> Where do we begin?
        /// <param name="target"></param> Where do we write?
        /// <param name="worker"></param> BackgroundWorker thread
        /// <param name="e"></param>
        private void GenXML(string source, string target, BackgroundWorker worker, DoWorkEventArgs e)
        {
            if (worker.CancellationPending)
            {
                e.Cancel = true;
            }
            else
            {
                XmlDocument directoryListing = new XmlDocument();
                directoryListing.LoadXml("<directory>" + "</directory>");

                XmlElement directoryContents = GetData(source, directoryListing, 0, 100, worker, e);
                directoryListing.DocumentElement.AppendChild(directoryContents);
                try
                {
                    directoryListing.Save(target);
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message, "Xml file save error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        /// <summary>
        /// Called recursively, this function returns all the sub-XmlElement nodes from
        /// our current position
        /// </summary>
        /// <param name="directory"></param> Root directory
        /// <param name="xmlDocument"></param> XmlDocument
        /// <param name="offset"></param> Percentage complete
        /// <param name="percent"></param> Percentage of overall task
        /// <param name="worker"></param> BackgroundWorker thread
        /// <param name="e"></param>
        /// <returns>XmlElement</returns>
        private XmlElement GetData(string directory, XmlDocument parentDirectory, float offset, float percent,
            BackgroundWorker worker, DoWorkEventArgs e)
        {
            XmlElement thisDirectory = parentDirectory.CreateElement("dir");
            DirectoryInfo currentDirectory = new DirectoryInfo(directory);
            FileSystemInfo[] foldersInDirectory = currentDirectory.GetDirectories();
            thisDirectory.SetAttribute("name", currentDirectory.Name);
            int numberOfDirectories = foldersInDirectory.Length;
            float directoryPercentage = percent / numberOfDirectories;

            if (worker.CancellationPending)
            {
                e.Cancel = true;
            }
            else
            {
                foreach (DirectoryInfo subDirectory in currentDirectory.GetDirectories())
                {
                    XmlElement subDirectoryDetails = GetData(directory + "\\" + subDirectory.Name, parentDirectory, offset, directoryPercentage, worker, e);
                    offset += directoryPercentage;
                    worker.ReportProgress((int)offset);
                    thisDirectory.AppendChild(subDirectoryDetails);
                }
                if (includeFiles.Checked)
                {
                    foreach (FileInfo file in currentDirectory.GetFiles())
                    {
                        XmlElement thisFile = parentDirectory.CreateElement("file");
                        thisFile.SetAttribute("name", file.Name);
                        thisDirectory.AppendChild(thisFile);
                    }
                }
            }

            return thisDirectory;
        }

        /// <summary>
        /// Called to initiate processing of the task by our BackgroundWorker thread
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            GenXML(sourceList.Items[sourceIndex].ToString(), targetList.Items[targetIndex].ToString(), worker, e);
        }

        /// <summary>
        /// Called when our BackgroundWorker thread ends for whatever reason
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            startButton.Enabled = true;
            startButton.Text = "Start";
            toolStripProgressBar1.Visible = false;
            if (!e.Cancelled)
            {
                toolStripStatusLabel1.Text = "";
                webBrowser1.Navigate(targetList.Items[targetIndex].ToString());
                webBrowser1.Refresh(WebBrowserRefreshOption.Completely);
                saveButton.Visible = true;
            }
            else
            {
                toolStripStatusLabel1.Text = "Cancelled";
            }
        }

        /// <summary>
        /// Progress reporting function for our BackgroundWorker thread
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            toolStripProgressBar1.Value = Math.Min(e.ProgressPercentage, 100);
        }

        /// <summary>
        /// Save the file as an image
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void saveButton_Click(object sender, EventArgs e)
        {
            // Create a Bitmap object to contain the contents of the WebBrowser control
            // The width of the image is determined by the displayed width of the WebBrowser, the
            // length of the image is determined by the WebBrowser control
            int realBrowserPositionX = this.Location.X + panel1.Location.X + webBrowser1.Location.X + 5;
            int realBrowserPositionY = this.Location.Y + panel1.Location.Y + webBrowser1.Location.Y + 30;
            int browserFullWidth = webBrowser1.Document.Body.ScrollRectangle.Width;
            int browserFullHeight = webBrowser1.Document.Body.ScrollRectangle.Height;
            int browserWindowWidth = webBrowser1.Width;
            int browserWindowHeight = webBrowser1.Height;
            int browserOffsetX = 0;
            int browserOffsetY = 0;
            Bitmap fullImage = new Bitmap(browserFullWidth, browserFullHeight);
            Graphics fullImageGraphics = Graphics.FromImage(fullImage);

            webBrowser1.Document.Body.ScrollTop = 0;

            do
            {
                int actualImageSegmentHeight = Math.Min(browserWindowHeight, browserFullHeight - browserOffsetY);
                int actualBrowserWindowOffsetY = Math.Min(browserOffsetY, browserWindowHeight - actualImageSegmentHeight);
                Bitmap sectionOfImage = new Bitmap(browserWindowWidth, actualImageSegmentHeight);
                Graphics sectionOfImageGraphics = Graphics.FromImage(sectionOfImage);
                sectionOfImageGraphics.CopyFromScreen(realBrowserPositionX,
                    realBrowserPositionY + actualBrowserWindowOffsetY,
                    0, 0, new Size(browserWindowWidth, actualImageSegmentHeight),
                    CopyPixelOperation.SourceCopy);
                fullImageGraphics.DrawImage(sectionOfImage, browserOffsetX, browserOffsetY,
                    browserWindowWidth, actualImageSegmentHeight);
                browserOffsetY += browserWindowHeight;
                webBrowser1.Document.Body.ScrollTop += browserWindowHeight;
            }
            while (browserOffsetY < browserFullHeight);

            // Show the save file dialog so that the user can choose to save the image in his choice of
            // supported formats
            saveFileDialog1.Filter = "Bitmap files (*.bmp)|*.bmp|Graphics Interchange Format files (*.gif)|*.gif|Joint Photographic Experts Group files (*.jpg)|*.jpg|Portable Network Graphics files (*.png)|*.png|Tagged Image File Format files (*.tif)|*.tif|All files (*.*)|*.*";
            saveFileDialog1.FileName = (saveFileDialog1.FileName == "" ? "XmlImage" : saveFileDialog1.FileName);
            saveFileDialog1.DefaultExt = "jpg";
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                try
                {
                    switch (Path.GetExtension(saveFileDialog1.FileName))
                    {
                        case "bmp":
                            fullImage.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                            break;
                        case "gif":
                            fullImage.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Gif);
                            break;
                        case "jpg":
                            fullImage.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                            break;
                        case "png":
                            fullImage.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Png);
                            break;
                        case "tif":
                            fullImage.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Tiff);
                            break;
                        default:
                            fullImage.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                            break;
                    }
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message, "Image file save error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United Kingdom United Kingdom
15+ years experience developing software and integration components for; SharePoint, Microsoft Office, SQL Server, Oracle, Meridio, Kofax, Trim Context, Convera Retrievalware, Rightfax Gateway, etc.
Using; C#, .NET Framework (1.0, 1.1, 2.0, 3.0), ASP.NET, VB6, C++/C, Web Services, SOAP, XML, SMTP, MFC, Shell scripting, VB scripting, IBM MQ series, etc.
Platforms; Windows 9x/2000/NT/XP/Vista, Unix (Solaris, HP-UX, Tru64), OpenVMS, VAX/VMS

Comments and Discussions