In this article, we will discuss about PDF generation
MainForm.cs
------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Org.BouncyCastle.Asn1.Cmp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Utilities;
using Rectangle = System.Drawing.Rectangle;
namespace AutoRegionScreenshotPDFV2
{
public partial class MainForm : Form
{
private Rectangle selectedRegion;
private bool regionSelected = false;
private bool capturing = false;
private string screenshotFolder;
private int screenshotCount = 0;
private NotifyIcon trayIcon;
private ContextMenuStrip trayMenu;
// Import Windows API functions for always on top
private const int SWP_NOSIZE = 0x0001;
private const int SWP_NOMOVE = 0x0002;
private const int SWP_NOACTIVATE = 0x0010;
private const int HWND_TOPMOST = -1;
private const int HWND_NOTOPMOST = -2;
[DllImport("user32.dll")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
public MainForm()
{
InitializeComponent();
this.KeyPreview = true;
this.KeyDown += Form1_KeyDown;
// Define folder path
screenshotFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Screenshots");
Directory.CreateDirectory(screenshotFolder);
// Initialize tray icon
InitializeTrayIcon();
// Set window to be always on top
SetAlwaysOnTop(true);
}
private void SetAlwaysOnTop(bool onTop)
{
SetWindowPos(this.Handle,
onTop ? (IntPtr)HWND_TOPMOST : (IntPtr)HWND_NOTOPMOST,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
private void InitializeTrayIcon()
{
trayMenu = new ContextMenuStrip();
trayMenu.Items.Add("Restore", null, (s, e) => RestoreFromTray());
trayMenu.Items.Add("Toggle Always On Top", null, (s, e) => ToggleAlwaysOnTop());
trayMenu.Items.Add("Exit", null, (s, e) => Application.Exit());
trayIcon = new NotifyIcon
{
Text = "Screenshot Region to PDF",
Icon = SystemIcons.Application,
ContextMenuStrip = trayMenu,
Visible = true
};
trayIcon.DoubleClick += (s, e) => RestoreFromTray();
}
private void ToggleAlwaysOnTop()
{
bool isCurrentlyOnTop = GetIsAlwaysOnTop();
SetAlwaysOnTop(!isCurrentlyOnTop);
if (this.Visible)
{
MessageBox.Show($"Always on top is now {(!isCurrentlyOnTop ? "enabled" : "disabled")}",
"Always On Top",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
// Get the current window style
const int GWL_EXSTYLE = -20;
const int WS_EX_TOPMOST = 0x00000008;
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
private bool GetIsAlwaysOnTop()
{
int style = GetWindowLong(this.Handle, GWL_EXSTYLE);
return (style & WS_EX_TOPMOST) != 0;
}
private void RestoreFromTray()
{
this.Show();
this.WindowState = FormWindowState.Normal;
this.ShowInTaskbar = true;
this.Activate();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (this.WindowState == FormWindowState.Minimized)
{
this.Hide();
this.ShowInTaskbar = false;
trayIcon.ShowBalloonTip(1000, "Still running", "The application is still running in the background", ToolTipIcon.Info);
}
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
// Clean up tray icon
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
this.WindowState = FormWindowState.Minimized;
}
else
{
trayIcon.Visible = false;
trayIcon.Dispose();
}
}
private void MainForm_Load(object sender, EventArgs e)
{
lblStatus.Text = "No region selected.";
}
private void btnSelectRegion_Click(object sender, EventArgs e)
{
// Temporarily disable always on top for region selection
SetAlwaysOnTop(false);
using (var selector = new RegionSelector2())
{
if (selector.ShowDialog() == DialogResult.OK)
{
selectedRegion = selector.SelectedRegion;
regionSelected = true;
lblStatus.Text = $"Region selected: {selectedRegion.Width}x{selectedRegion.Height}";
}
}
// Restore always on top
SetAlwaysOnTop(true);
}
private void btnStart_Click(object sender, EventArgs e)
{
if (!regionSelected)
{
MessageBox.Show("Please select a region first.");
return;
}
capturing = true;
screenshotCount = 0;
lblStatus.Text = "Started. Press 'P' to capture screenshots.";
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (!capturing || !regionSelected) return;
if (e.KeyCode == Keys.P)
{
CaptureScreenshot();
}
}
private void CaptureScreenshot()
{
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmssfff");
string fileName = $"Screenshot_{timestamp}.png";
string filePath = Path.Combine(screenshotFolder, fileName);
using (Bitmap bmp = new Bitmap(selectedRegion.Width, selectedRegion.Height))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(selectedRegion.Location, Point.Empty, selectedRegion.Size);
}
bmp.Save(filePath, ImageFormat.Png);
}
screenshotCount++;
lblStatus.Text = $"Captured: {fileName} | Total: {screenshotCount}";
// Show balloon tip when minimized
if (this.WindowState == FormWindowState.Minimized)
{
trayIcon.ShowBalloonTip(1000, "Screenshot Captured", fileName, ToolTipIcon.Info);
}
}
private void btnStopSave_Click(object sender, EventArgs e)
{
CreatePdfFromImages(screenshotFolder);
}
private void CreatePdfFromImages(string screenshotsFolder)
{
try
{
string[] imageFiles = Directory.GetFiles(screenshotsFolder, "Screenshot_*.png");
if (imageFiles.Length == 0)
{
MessageBox.Show("No screenshots found to create PDF", "Warning",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// Sort files by timestamp in filename
Array.Sort(imageFiles, (a, b) =>
{
try
{
// Extract timestamp parts from filename (format: Screenshot_yyyyMMdd_HHmmssfff)
string filenameA = Path.GetFileNameWithoutExtension(a);
string filenameB = Path.GetFileNameWithoutExtension(b);
// Combine date and time parts (after first underscore)
string timeStringA = filenameA.Substring(filenameA.IndexOf('_') + 1).Replace("_", "");
string timeStringB = filenameB.Substring(filenameB.IndexOf('_') + 1).Replace("_", "");
return DateTime.ParseExact(timeStringA, "yyyyMMddHHmmssfff", null)
.CompareTo(DateTime.ParseExact(timeStringB, "yyyyMMddHHmmssfff", null));
}
catch (Exception ex)
{
MessageBox.Show($"Error parsing screenshot timestamps:\n{ex.Message}\nFilename A: {a}\nFilename B: {b}", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return 0; // Default sort if parsing fails
}
});
string pdfFilename = $"Screenshots_{DateTime.Now:yyyyMMdd_HHmmss}.pdf";
string pdfPath = Path.Combine(screenshotsFolder, pdfFilename);
using (FileStream fs = new FileStream(pdfPath, FileMode.Create))
{
Document document = new Document(PageSize.A4.Rotate());
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
foreach (string imageFile in imageFiles)
{
try
{
using (var imgStream = new FileStream(imageFile, FileMode.Open))
{
iTextSharp.text.Image pdfImg = iTextSharp.text.Image.GetInstance(imgStream);
pdfImg.ScaleToFit(document.PageSize.Width - 50, document.PageSize.Height - 50);
pdfImg.Alignment = Element.ALIGN_CENTER;
document.Add(pdfImg);
document.NewPage();
}
}
catch (Exception ex)
{
MessageBox.Show($"Error processing image {imageFile}:\n{ex.Message}", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
document.Close();
}
DeleteImageFiles(pdfPath, imageFiles);
MessageBox.Show($"PDF successfully saved to:\n{pdfPath}", "Success",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"Failed to save PDF:\n{ex.Message}", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void DeleteImageFiles(string pdfPath, string[] imageFiles)
{
// DELETE IMAGES ONLY AFTER PDF IS SUCCESSFULLY CREATED
if (File.Exists(pdfPath))
{
foreach (var imageFile in imageFiles)
{
try
{
File.Delete(imageFile);
}
catch (Exception ex)
{
// Optional: log instead of showing popup
Console.WriteLine($"Failed to delete {imageFile}: {ex.Message}");
}
}
}
}
}
public class RegionSelector2 : Form
{
private Point startPoint;
private Point endPoint;
private Rectangle selectedRect;
private bool selecting = false;
public Rectangle SelectedRegion => selectedRect;
public RegionSelector2()
{
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
this.Opacity = 0.3;
this.BackColor = Color.Black;
this.TopMost = true;
this.Cursor = Cursors.Cross;
this.DoubleBuffered = true;
this.MouseDown += RegionSelector_MouseDown;
this.MouseMove += RegionSelector_MouseMove;
this.MouseUp += RegionSelector_MouseUp;
this.Paint += RegionSelector_Paint;
this.KeyDown += (s, e) => { if (e.KeyCode == Keys.Escape) this.DialogResult = DialogResult.Cancel; };
}
private void RegionSelector_MouseDown(object sender, MouseEventArgs e)
{
selecting = true;
startPoint = e.Location;
endPoint = e.Location;
Invalidate();
}
private void RegionSelector_MouseMove(object sender, MouseEventArgs e)
{
if (selecting)
{
endPoint = e.Location;
Invalidate();
}
}
private void RegionSelector_MouseUp(object sender, MouseEventArgs e)
{
selecting = false;
selectedRect = GetRectangle(startPoint, endPoint);
this.DialogResult = DialogResult.OK;
this.Close();
}
private void RegionSelector_Paint(object sender, PaintEventArgs e)
{
if (selecting)
{
Rectangle rect = GetRectangle(startPoint, endPoint);
using (Pen pen = new Pen(Color.Red, 2))
{
e.Graphics.DrawRectangle(pen, rect);
}
}
}
private Rectangle GetRectangle(Point p1, Point p2)
{
return new Rectangle(
Math.Min(p1.X, p2.X),
Math.Min(p1.Y, p2.Y),
Math.Abs(p1.X - p2.X),
Math.Abs(p1.Y - p2.Y));
}
}
}
MainForm.Designer.cs
-------------------------------------
using System.Drawing;
using System;
using System.Windows.Forms;
namespace AutoRegionScreenshotPDFV2
{
partial class MainForm
{
private System.ComponentModel.IContainer components = null;
private System.Windows.Forms.Button btnSelectRegion;
private System.Windows.Forms.Button btnStart;
private System.Windows.Forms.Button btnStopSave;
private System.Windows.Forms.Label lblStatus;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.btnSelectRegion = new System.Windows.Forms.Button();
this.btnStart = new System.Windows.Forms.Button();
this.btnStopSave = new System.Windows.Forms.Button();
this.lblStatus = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// btnSelectRegion
//
this.btnSelectRegion.Location = new System.Drawing.Point(12, 12);
this.btnSelectRegion.Name = "btnSelectRegion";
this.btnSelectRegion.Size = new System.Drawing.Size(103, 35);
this.btnSelectRegion.TabIndex = 0;
this.btnSelectRegion.Text = "Select Region";
this.btnSelectRegion.UseVisualStyleBackColor = true;
this.btnSelectRegion.Click += new System.EventHandler(this.btnSelectRegion_Click);
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(15, 65);
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(100, 35);
this.btnStart.TabIndex = 1;
this.btnStart.Text = "Start";
this.btnStart.UseVisualStyleBackColor = true;
this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
//
// btnStopSave
//
this.btnStopSave.Location = new System.Drawing.Point(15, 116);
this.btnStopSave.Name = "btnStopSave";
this.btnStopSave.Size = new System.Drawing.Size(100, 35);
this.btnStopSave.TabIndex = 2;
this.btnStopSave.Text = "Stop and Save";
this.btnStopSave.UseVisualStyleBackColor = true;
this.btnStopSave.Click += new System.EventHandler(this.btnStopSave_Click);
//
// lblStatus
//
this.lblStatus.Location = new System.Drawing.Point(9, 171);
this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(110, 75);
this.lblStatus.TabIndex = 3;
this.lblStatus.Text = "Status goes here";
//
// MainForm
//
this.ClientSize = new System.Drawing.Size(131, 255);
this.Controls.Add(this.lblStatus);
this.Controls.Add(this.btnStopSave);
this.Controls.Add(this.btnStart);
this.Controls.Add(this.btnSelectRegion);
this.Name = "MainForm";
this.Text = "Screenshot Region to PDF";
this.Load += new System.EventHandler(this.MainForm_Load);
this.ResumeLayout(false);
}
}
}
MainForm2.cs
----------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using iTextSharp.text.pdf;
using iTextSharp.text;
using Rectangle = System.Drawing.Rectangle;
namespace AutoRegionScreenshotPDFV2
{
public partial class MainForm2 : Form
{
private Rectangle selectedRegion;
private bool regionSelected = false;
private bool capturing = false;
private string screenshotFolder;
private int screenshotCount = 0;
public MainForm2()
{
InitializeComponent();
this.KeyPreview = true;
this.KeyDown += Form1_KeyDown;
// Define folder path
screenshotFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Screenshots");
Directory.CreateDirectory(screenshotFolder);
}
private void MainForm_Load(object sender, EventArgs e)
{
lblStatus.Text = "No region selected.";
}
private void btnSelectRegion_Click(object sender, EventArgs e)
{
using (var selector = new RegionSelector())
{
if (selector.ShowDialog() == DialogResult.OK)
{
selectedRegion = selector.SelectedRegion;
regionSelected = true;
lblStatus.Text = $"Region selected: {selectedRegion.Width}x{selectedRegion.Height}";
}
}
}
private void btnStart_Click(object sender, EventArgs e)
{
if (!regionSelected)
{
MessageBox.Show("Please select a region first.");
return;
}
capturing = true;
screenshotCount = 0;
lblStatus.Text = "Started. Press 'P' to capture screenshots.";
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (!capturing || !regionSelected) return;
if (e.KeyCode == Keys.P)
{
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmssfff");
string fileName = $"Screenshot_{timestamp}.png";
string filePath = Path.Combine(screenshotFolder, fileName);
using (Bitmap bmp = new Bitmap(selectedRegion.Width, selectedRegion.Height))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(selectedRegion.Location, Point.Empty, selectedRegion.Size);
}
bmp.Save(filePath, ImageFormat.Png);
}
screenshotCount++;
lblStatus.Text = $"Captured: {fileName} | Total: {screenshotCount}";
}
}
private void btnStopSave_Click(object sender, EventArgs e)
{
var imageFiles = Directory.GetFiles(screenshotFolder, "*.png")
.OrderBy(f => f) // Ensures sequential order by filename
.ToList();
CreatePdfFromImages(screenshotFolder);
//if (imageFiles.Count == 0)
//{
// MessageBox.Show("No screenshots found to save.");
// return;
//}
//SaveFileDialog saveDialog = new SaveFileDialog
//{
// Filter = "PDF files (*.pdf)|*.pdf",
// Title = "Save PDF"
//};
//if (saveDialog.ShowDialog() == DialogResult.OK)
//{
// using (FileStream fs = new FileStream(saveDialog.FileName, FileMode.Create))
// {
// using (Document doc = new Document())
// {
// PdfWriter.GetInstance(doc, fs);
// doc.Open();
// foreach (var imgPath in imageFiles)
// {
// var img = iTextSharp.text.Image.GetInstance(imgPath);
// img.ScaleToFit(doc.PageSize.Width - 20, doc.PageSize.Height - 20);
// img.Alignment = Element.ALIGN_CENTER;
// doc.Add(img);
// doc.NewPage();
// }
// doc.Close();
// }
// }
// MessageBox.Show("PDF created successfully.");
// lblStatus.Text = "PDF saved.";
// capturing = false;
//}
}
private void CreatePdfFromImages(string screenshotsFolder)
{
try
{
string[] imageFiles = Directory.GetFiles(screenshotsFolder, "Screenshot_*.png");
if (imageFiles.Length == 0)
{
MessageBox.Show("No screenshots found to create PDF", "Warning",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// Sort files numerically
Array.Sort(imageFiles, (a, b) =>
{
int numA = int.Parse(Path.GetFileNameWithoutExtension(a).Split('_')[1]);
int numB = int.Parse(Path.GetFileNameWithoutExtension(b).Split('_')[1]);
return numA.CompareTo(numB);
});
string pdfFilename = $"Screenshots_{DateTime.Now:yyyyMMdd_HHmmss}.pdf";
string pdfPath = Path.Combine(screenshotsFolder, pdfFilename);
using (FileStream fs = new FileStream(pdfPath, FileMode.Create))
{
Document document = new Document(PageSize.A4.Rotate());
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
foreach (string imageFile in imageFiles)
{
using (var imgStream = new FileStream(imageFile, FileMode.Open))
{
iTextSharp.text.Image pdfImg = iTextSharp.text.Image.GetInstance(imgStream);
pdfImg.ScaleToFit(document.PageSize.Width - 50, document.PageSize.Height - 50);
pdfImg.Alignment = Element.ALIGN_CENTER;
document.Add(pdfImg);
document.NewPage();
}
}
document.Close();
}
// Show success message with PDF path
MessageBox.Show($"PDF successfully saved to:\n{pdfPath}", "Success",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
// Show error message
MessageBox.Show($"Failed to save PDF:\n{ex.Message}", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
public class RegionSelector : Form
{
private Point startPoint;
private Point endPoint;
private Rectangle selectedRect;
private bool selecting = false;
public Rectangle SelectedRegion => selectedRect;
public RegionSelector()
{
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
this.Opacity = 0.3;
this.BackColor = Color.Black;
this.TopMost = true;
this.Cursor = Cursors.Cross;
this.DoubleBuffered = true;
this.MouseDown += RegionSelector_MouseDown;
this.MouseMove += RegionSelector_MouseMove;
this.MouseUp += RegionSelector_MouseUp;
this.Paint += RegionSelector_Paint;
this.KeyDown += (s, e) => { if (e.KeyCode == Keys.Escape) this.DialogResult = DialogResult.Cancel; };
}
private void RegionSelector_MouseDown(object sender, MouseEventArgs e)
{
selecting = true;
startPoint = e.Location;
endPoint = e.Location;
Invalidate();
}
private void RegionSelector_MouseMove(object sender, MouseEventArgs e)
{
if (selecting)
{
endPoint = e.Location;
Invalidate();
}
}
private void RegionSelector_MouseUp(object sender, MouseEventArgs e)
{
selecting = false;
selectedRect = GetRectangle(startPoint, endPoint);
this.DialogResult = DialogResult.OK;
this.Close();
}
private void RegionSelector_Paint(object sender, PaintEventArgs e)
{
if (selecting)
{
Rectangle rect = GetRectangle(startPoint, endPoint);
using (Pen pen = new Pen(Color.Red, 2))
{
e.Graphics.DrawRectangle(pen, rect);
}
}
}
private Rectangle GetRectangle(Point p1, Point p2)
{
return new Rectangle(
Math.Min(p1.X, p2.X),
Math.Min(p1.Y, p2.Y),
Math.Abs(p1.X - p2.X),
Math.Abs(p1.Y - p2.Y));
}
}
}
0 comments:
Post a Comment