主窗体代码
- 主窗体中添加三个截图按钮,根据不同按钮实现不同的截图功能,在截图前隐藏该主窗体,否则会截到主窗体,添加一定的延时,否则还是会截到主窗体,因为主窗体可能未隐藏成功。截图成功后再显示子窗体和主窗体。
public partial class MainForm : Form
{
FrmScreenshotEditor frmScreenshotEditor = new FrmScreenshotEditor();
public MainForm()
{
InitializeComponent();
this.CenterToParent();
this.Location = new Point(100,100);
this.MaximumSize = this.Size;
this.MinimumSize = this.Size;
}
private void Btn_FullScreen_Click(object sender, EventArgs e)
{
Screenshot(frmScreenshotEditor,1);
}
private void Btn_WorkingArea_Click(object sender, EventArgs e)
{
Screenshot(frmScreenshotEditor, 2);
}
private void Btn_ScreenArea_Click(object sender, EventArgs e)
{
Screenshot(frmScreenshotEditor);
}
private void Screenshot(FrmScreenshotEditor form, int mode = 0)
{
this.Hide();
form = new FrmScreenshotEditor();
FrmScreenshot frmScreenshot = new FrmScreenshot(form, mode);
if (mode == 0)
{
frmScreenshot.ShowDialog();
}
if (form.Image == null)
{
this.Show();
return;
}
else
{
Image image = new Bitmap(form.Image);
form.PixelSize = image.Size;
Debug.WriteLine($"图像大小:X = {image.Width},Y = {image.Height}");
form.ShowDialog();
this.Show();
}
}
}
截图窗体代码
- 声明DPI感知方法,适应系统缩放显示。实现了基本的全屏、工作区、区域截图等功能。区域截图时显示桌面鼠标定及截图大小功能。
#region 方法|自定义方法
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
private void ScreenshotMethod(int mode)
{
switch (mode)
{
case 0:
frm_ScreenshotEidtor.Image = CaptureSelectedRegion();
break;
case 1:
Thread.Sleep(300);
frm_ScreenshotEidtor.Image = CaptureFullScreen();
this.Close();
break;
case 2:
Thread.Sleep(300);
frm_ScreenshotEidtor.Image = CaptureWorkingArea();
this.Close();
break;
default:
frm_ScreenshotEidtor.Image = CaptureSelectedRegion();
break;
}
}
public Bitmap CaptureSelectedRegion()
{
int captureX = Math.Min(startPoint.X, endPoint.X);
int captureY = Math.Min(startPoint.Y, endPoint.Y);
int captureWidth = Math.Abs(startPoint.X - endPoint.X);
int captureHeight = Math.Abs(startPoint.Y - endPoint.Y);
if (captureWidth <= 0 || captureHeight <= 0) return null;
float dpiScaleX, dpiScaleY;
using (Graphics g = this.CreateGraphics())
{
dpiScaleX = g.DpiX / 96f;
dpiScaleY = g.DpiY / 96f;
}
Point upperLeftSource = this.PointToScreen(new Point(
(int)(captureX * dpiScaleX),
(int)(captureY * dpiScaleY)));
int physicalWidth = (int)(captureWidth * dpiScaleX);
int physicalHeight = (int)(captureHeight * dpiScaleY);
this.Invalidate();
Debug.WriteLine($"起始位置:{startPoint},结束位置:{endPoint}");
Debug.WriteLine($"采集X:{captureX},采集Y:{captureY}");
Debug.WriteLine($"采集宽度:{captureWidth},采集高度:{captureHeight}");
Debug.WriteLine($"转换点:{upperLeftSource}");
Bitmap bitmap = new Bitmap(captureWidth, captureHeight);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(upperLeftSource, Point.Empty, new Size(captureWidth, captureHeight));
}
return bitmap;
}
public Bitmap CaptureFullScreen()
{
Rectangle bounds = Screen.GetBounds(Point.Empty);
float dpiScaleX, dpiScaleY;
using (Graphics g = this.CreateGraphics())
{
dpiScaleX = g.DpiX / 96f;
dpiScaleY = g.DpiY / 96f;
}
int physicalWidth = (int)(bounds.Width * dpiScaleX);
int physicalHeight = (int)(bounds.Height * dpiScaleY);
Bitmap bitmap = new Bitmap(physicalWidth, physicalHeight);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(new Point(0,0), Point.Empty, new Size(physicalWidth, physicalHeight));
}
return bitmap;
}
public Bitmap CaptureWorkingArea()
{
Rectangle bounds = Screen.PrimaryScreen.WorkingArea;
float dpiScaleX, dpiScaleY;
using (Graphics g = this.CreateGraphics())
{
dpiScaleX = g.DpiX / 96f;
dpiScaleY = g.DpiY / 96f;
}
int physicalWidth = (int)(bounds.Width * dpiScaleX);
int physicalHeight = (int)(bounds.Height * dpiScaleY);
Bitmap bitmap = new Bitmap(physicalWidth, physicalHeight);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(new Point(0, 0), Point.Empty, new Size(physicalWidth, physicalHeight));
}
return bitmap;
}
private void DrawMousePosition(Graphics graphics)
{
using (Pen pen = new Pen(Color.Red, 1))
{
int x = Math.Min(startPoint.X, endPoint.X);
int y = Math.Min(startPoint.Y, endPoint.Y);
int width = Math.Abs(startPoint.X - endPoint.X);
int height = Math.Abs(startPoint.Y - endPoint.Y);
DrawSelectedRegion(graphics, new Rectangle(x, y, width, height));
string sizeText = $"{width} x {height}";
Font font = new Font("Arial", 14);
SizeF textSize = graphics.MeasureString(sizeText, font);
float textX = x + width - textSize.Width - 5;
float textY = y + height - textSize.Height - 5;
if (textX < x) textX = x + 5;
if (textY < y) textY = y + 5;
graphics.FillRectangle(Brushes.White, textX - 2, textY - 2, textSize.Width + 4, textSize.Height + 4);
graphics.DrawString(sizeText, font, Brushes.Blue, textX, textY);
}
}
private void DrawSelectedRegion(Graphics graphics, Rectangle selectionRect)
{
using (Brush overlayBrush = new SolidBrush(Color.FromArgb(128, Color.Black)))
{
graphics.FillRectangle(overlayBrush, this.ClientRectangle);
}
graphics.SetClip(selectionRect, CombineMode.Exclude);
graphics.Clear(Color.FromArgb(255, 0, 0, 0));
graphics.ResetClip();
using (Pen pen = new Pen(Color.Blue, 1))
{
graphics.DrawRectangle(pen, selectionRect);
}
}
#endregion