using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Drawing.Imaging; using System.Drawing.Drawing2D; namespace sharpcapture { public partial class ScreenshotWindow : Form { private const float PEN_WIDTH = 2f; private Bitmap capturedBitmap; float zoom = 1; public Bitmap CapturedBitmap { get { return capturedBitmap; } set { capturedBitmap = value; int maxWidth = Screen.PrimaryScreen.Bounds.Width; int maxHeight = Screen.PrimaryScreen.Bounds.Height; int width = capturedBitmap.Width; int height = capturedBitmap.Height; if ((width / maxWidth) >= 1 || (height / maxHeight) >= 1) { // Allow for 10% of space as well Zoom = (float)Math.Min( maxWidth / (1.1 * width), maxHeight / (1.1 * height)); } else { Zoom = 1; } } } public float Zoom { get { return zoom; } set { zoom = value; SetClientSizeCore((int)(capturedBitmap.Width * zoom), (int)(capturedBitmap.Height * zoom) + toolStrip.Height); Invalidate(); } } BufferedGraphicsContext context; BufferedGraphics buffer; private Point? firstPoint; // Mouse coordinates int mouseX; int mouseY; public ScreenshotWindow(Bitmap capturedBitmap) { InitializeComponent(); InitializaGraphics(); CapturedBitmap = capturedBitmap; CopyToClipboard(); } private void InitializaGraphics() { context = new BufferedGraphicsContext(); buffer = context.Allocate(this.toolStripContainer.ContentPanel.CreateGraphics(), this.DisplayRectangle); } private void CopyToClipboard() { Clipboard.SetDataObject(capturedBitmap, true); } private void SaveScreenshot() { SaveFileDialog saveScreenshot = new SaveFileDialog(); saveScreenshot.Filter = "PNG Image|*.png|JPEG Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif"; if (capturedBitmap != null && saveScreenshot.ShowDialog() == DialogResult.OK) { capturedBitmap.Save(saveScreenshot.FileName); } } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { Exit(); } private void Exit() { context.Dispose(); Close(); } private void MainWindow_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Escape) { Exit(); } else if (e.Control && e.KeyCode == Keys.S) { SaveScreenshot(); } } protected override void OnPaint(PaintEventArgs e) { if (capturedBitmap != null) { if (zoom != 1) { buffer.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor; buffer.Graphics.DrawImage( capturedBitmap, new Rectangle(0, toolStrip.Height, (int)(capturedBitmap.Size.Width * zoom), (int)(capturedBitmap.Size.Height * zoom) + toolStrip.Height), new Rectangle(0, 0, capturedBitmap.Size.Width, capturedBitmap.Size.Height), GraphicsUnit.Pixel); } // Avoid distorsion else { buffer.Graphics.DrawImage( capturedBitmap, new Rectangle(0, 0, capturedBitmap.Size.Width, capturedBitmap.Size.Height), new Rectangle(0, 0, capturedBitmap.Size.Width, capturedBitmap.Size.Height), GraphicsUnit.Pixel); } } if (firstPoint.HasValue && toolStrip.Visible) { DrawShape(buffer.Graphics, firstPoint.Value, new Point(mouseX, mouseY), true); } buffer.Render(); } private void DrawShape(Graphics g, Point p1, Point p2, bool temp) { Color color = temp ? Color.FromArgb(128, btnPicker.BackColor) : btnPicker.BackColor; Pen pen = new Pen(color, PEN_WIDTH); int x = Math.Min(p1.X, p2.X); int y = Math.Min(p1.Y, p2.Y); int width = Math.Abs(p1.X - p2.X); int height = Math.Abs(p1.Y - p2.Y); if (Control.ModifierKeys == Keys.Control) { // Align horizontally if (width > height) { p2.Y = p1.Y; } // Align vertically else { p2.X = p1.X; } height = width; } if (!temp) firstPoint = null; if (btnLine.Checked) { g.DrawLine(pen, p1, p2); } else if (btnPath.Checked) { g.DrawLine(pen, p1, p2); if (!temp) firstPoint = p2; } else if (btnRect.Checked) { g.DrawRectangle(pen, new Rectangle(x, y, width, height)); } else if (btnEllipse.Checked) { g.DrawEllipse(pen, new Rectangle(x, y, width, height)); } else if (btnFilledRect.Checked) { g.FillRectangle(new SolidBrush(color), new Rectangle(x, y, width, height)); } else if (btnFilledEllipse.Checked) { g.FillEllipse(new SolidBrush(color), new Rectangle(x, y, width, height)); } } private void ScreenshotWindow_MouseMove(object sender, MouseEventArgs e) { mouseX = e.X; mouseY = e.Y; if (firstPoint != null) { Invalidate(); } } protected override void OnPaintBackground(PaintEventArgs e) { // NOOP //base.OnPaintBackground(e); } private void MainWindow_Resize(object sender, EventArgs e) { InitializaGraphics(); } private void saveButton_Click(object sender, EventArgs e) { SaveScreenshot(); } private void toolStripButton_Click(object sender, EventArgs e) { if (sender == btnPicker) { colorDialog.Color = btnPicker.BackColor; if (colorDialog.ShowDialog(this) == DialogResult.OK) { btnPicker.BackColor = colorDialog.Color; } } else if (sender == btnZoomMore) { if (zoom < 1) zoom *= 2; else Zoom++; } else if (sender == btnZoomLess) { if (zoom > 0.25) { if (zoom > 1) zoom--; else Zoom /= 2; } } else { btnLine.Checked = false; btnPath.Checked = false; btnRect.Checked = false; btnEllipse.Checked = false; btnFilledRect.Checked = false; btnFilledEllipse.Checked = false; ((ToolStripButton)sender).Checked = true; } } private void zoomComboBox_SelectedIndexChanged(object sender, EventArgs e) { switch (toolStripComboBox1.SelectedIndex) { case 0: Zoom = 0.25f; break; case 1: Zoom = 0.5f; break; case 2: Zoom = 0.75f; break; case 3: Zoom = 1; break; case 4: Zoom = 1.5f; break; // >= 200% default: Zoom = toolStripComboBox1.SelectedIndex - 3; break; } } private void ScreenshotWindow_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { if (firstPoint == null) { firstPoint = new Point(e.X, e.Y); } else { Graphics g = Graphics.FromImage(capturedBitmap); //DrawShape(g, new Point((int)(firstPoint.Value.X / zoom), (int)(firstPoint.Value.Y / zoom)), new Point((int)(e.X / zoom), (int)(e.Y / zoom)), false); DrawShape(g, new Point(firstPoint.Value.X, firstPoint.Value.Y), new Point(e.X, e.Y), false); Invalidate(); CopyToClipboard(); } } if (e.Button == MouseButtons.Right) { if (firstPoint != null) { firstPoint = null; Invalidate(); } } } } }