制作类似QQ截图软件
??? 最近在學習GDI,發現網上幾篇文章在講截圖軟件制作方法,學習了一點知識,在這里分享一下. ?
??? 主要是調用WinAPI中的函數來完成主要功能.關鍵的函數有2個,一個是CreateDC,利用這個函數來創建一個顯示器屏幕的DC(設備環境),作為源DC,再創建一個Image圖像,通過這個圖像的Graphics.GetHdc()方法來獲取另一個DC,作為目標DC,這2個DC主要是留給第二個函數用的;第二個函數是BitBlt,這個函數將源DC上的像素掃描到目標DC中,在這里就是將顯示器屏幕的像素掃描到我們創建的Image圖片上.
??? 掃描完成之后得到的Image圖像就是現在的全屏圖,可以將圖片保存或者拷貝待用.這就實現了全屏截圖的功能.
??? 接下來是實現局部截圖.首先將全屏截圖Image通過畫圖畫在Winform窗體上,這個可以用窗體的Paint事件來實現,當窗體改變的時候,Paint事件就會被觸發.局部截圖就是在已經畫上了全屏圖片的Winform窗體上面再畫矩形,然后調用Graphics的方法DrawImage,將矩形區域的截圖保存在開始創建的Image中,這樣就得到了局部截圖,可以將圖片保存或者拷貝待用.
??? 功能基本上就實現了.需要注意的是,在窗體中畫的矩形是可反轉矩形,調用的是ControlPaint.DrawReversibleFrame()方法,這個方法需要執行2次才能畫出矩形.
??? 主窗口代碼:
public partial class Form1 : Form{
//*******************Global Varibles******************
private Bitmap MyImage = null;
private bool StartedCrop = false;
Point StartPoint = new Point(0, 0);
Rectangle SelectRect = new Rectangle();
int DeltaX = 0;
int DeltaY = 0;
//****************************************************
[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
public static extern int BitBlt(
IntPtr hDestDC,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hSrcDC,
int xSrc,
int ySrc,
System.Int32 dwRop
);
[DllImport("gdi32.dll", EntryPoint = "CreateDC")]
public static extern IntPtr CreateDC(
string lpDriverName,
string lpDeviceName,
string lpOutput,
IntPtr lpInitData
);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.Visible = false;
Thread.Sleep(100);
IntPtr dc1 = CreateDC("DISPLAY", null, null, (IntPtr)null);
Graphics g1 = Graphics.FromHdc(dc1);
MyImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, g1);
Graphics g2 = Graphics.FromImage(MyImage);
//Visible = false;
dc1 = g1.GetHdc();
IntPtr dc2 = g2.GetHdc();
BitBlt(dc2, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height,
dc1, 0, 0, 13369376);
g1.ReleaseHdc(dc1);
g2.ReleaseHdc(dc2);
this.Visible = true;
this.SetBounds(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
this.Cursor = Cursors.Cross;
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (StartedCrop == false)
{
DeltaX = 0;
DeltaY = 0;
}
StartedCrop = true;
StartPoint = new Point(e.X,e.Y);
SelectRect.Width = 0;
SelectRect.Height = 0;
SelectRect.X = e.X;
SelectRect.Y = e.Y;
Invalidate();
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Form thisform = (Form)sender;
if (StartedCrop)
{
DeltaX = e.X - StartPoint.X;
if (DeltaX < 0)
DeltaX = 0;
DeltaY = e.Y - StartPoint.Y;
if (DeltaY < 0)
DeltaY = 0;
ControlPaint.DrawReversibleFrame(thisform.RectangleToScreen(SelectRect), Color.Black, FrameStyle.Dashed);
SelectRect.Width = e.X - SelectRect.X;
SelectRect.Height = e.Y - SelectRect.Y;
ControlPaint.DrawReversibleFrame(thisform.RectangleToScreen(SelectRect), Color.Black, FrameStyle.Dashed);
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (DeltaX == 0 || DeltaY == 0)
{
return;
}
StartedCrop = false;
SelectRect.X = e.X - StartPoint.X;
SelectRect.Y = e.Y - StartPoint.Y;
this.Cursor = Cursors.Cross;
Bitmap theImage = new Bitmap(DeltaX, DeltaY);
Graphics g = Graphics.FromImage(theImage);
Rectangle destRect = new Rectangle(0, 0, DeltaX, DeltaY);
g.DrawImage(MyImage, destRect, StartPoint.X, StartPoint.Y, theImage.Width, theImage.Height, GraphicsUnit.Pixel);
MyImage = (Bitmap)theImage.Clone();
this.SetBounds(0, 0, MyImage.Width, MyImage.Height);
this.Visible = false;
frmOptions optionsForm = new frmOptions();
optionsForm.imageToSaveOrCopy = MyImage;
optionsForm.ShowDialog();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (MyImage != null)
e.Graphics.DrawImage(MyImage, ClientRectangle, 0, 0, MyImage.Width, MyImage.Height, GraphicsUnit.Pixel);
}
private void Form1_Resize(object sender, EventArgs e)
{
Invalidate();
}
private void Form1_DoubleClick(object sender, EventArgs e)
{
Application.Exit();
}
}
??? 選項窗口代碼(frmOptions)主要有2個按鈕,用來保存或者拷貝截取的圖片:
public partial class frmOptions : Form{
public Image imageToSaveOrCopy;
public frmOptions()
{
InitializeComponent();
}
private void frmOptions_Load(object sender, EventArgs e)
{
}
private void btnSave_Click(object sender, EventArgs e)
{
if (imageToSaveOrCopy == null) {
MessageBox.Show("You have not choose the image! Please restart this program!");
Application.Exit();
}
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "*.jpg|*.jpg";
sfd.AddExtension = true;
sfd.FileName = "1.jpg";
if (sfd.ShowDialog() == DialogResult.OK)
{
imageToSaveOrCopy.Save(sfd.FileName);
}
Application.Exit();
}
private void btnCopy_Click(object sender, EventArgs e)
{
if (imageToSaveOrCopy == null)
{
MessageBox.Show("You have not choose the image! Please restart this program!");
Application.Exit();
}
try
{
Clipboard.SetImage(imageToSaveOrCopy);
}
catch (Exception ex)
{
MessageBox.Show("Copy to clipboard error:\r\n"+ex.Message);
}
Application.Exit();
}
}
??? 由于局部截圖的時候需要在屏幕上面畫圖,而要想屏幕位置(Point)和我們主窗體的位置一一對應起來,就需要將主窗體最大化到全屏幕,為了效果好點,可以將
窗體的BorderStyle屬性設置為None.這樣整個工作就完成了.
轉載于:https://www.cnblogs.com/johnsmith/archive/2012/01/02/2309775.html
總結
以上是生活随笔為你收集整理的制作类似QQ截图软件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转载]内容首页设计经验
- 下一篇: [z]Qt 内存管理机制