最近手头工作比较轻松了一点就继续研究和完善之前的录屏软件,使用AForge最大的问题在于:最原始的只能够录全屏,而自定义的录屏需要更改非常多的细节:like follows:

1、需要支持区域化录屏;

2、需要支持麦克风录音,并且混音在视频中,同步;

3、需要支持系统声音录取、并且需要混音在视频中,同步;

4、需要支持捕获光标,并且自定义颜色、描边,最重要的是你需要在区域录屏的时候支持坐标位置更新(相对比较难);

前面3个已经在前面的文章介绍了,这里不再赘述。着重列出第4点的内容以及如何解决。如果正在研究录屏这块的朋友们,千万别去copy那什么网上有限制时间录制和收费的录制,特别是有些很恶心的还发表长篇大论写的如何如何实现(的确技术不可否认是实现了),其实最后还是要你付费才能完全使用,就问你恶不恶心!

好了,废话不多说,我们来一一解决;

首先获取系统光标有两种方式,第一种是直接通过系统API进行获取光标,这个是完全记录系统光标在做什么。随着系统光标变化而变化的。这边有用到的是几个类:

第一种方式:【CursorHelper.cs】、【GDIStuff.cs】、【Win32Stuff.cs】相对复杂一些;我就在代码中直接显示就好了,不需要引用任何其他的东西;

    /// <summary>
/// The rt global cursor.
/// </summary>
public class CursorHelper
{
#region Constants /// <summary>
/// The curso r_ showing.
/// </summary>
private const int CURSOR_SHOWING = ; #endregion #region Public Methods and Operators /// <summary>
/// The capture cursor.
/// </summary>
/// <param name="x">
/// The x.
/// </param>
/// <param name="y">
/// The y.
/// </param>
/// <returns>
/// The <see cref="Bitmap"/>.
/// </returns>
public static Bitmap CaptureCursor(ref int x, ref int y)
{
Win32Stuff.CURSORINFO cursorInfo = new Win32Stuff.CURSORINFO();
cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);
if (!Win32Stuff.GetCursorInfo(out cursorInfo))
{
return null;
} if (cursorInfo.flags != Win32Stuff.CURSOR_SHOWING)
{
return null;
} IntPtr hicon = Win32Stuff.CopyIcon(cursorInfo.hCursor);
if (hicon == IntPtr.Zero)
{
return null;
} Win32Stuff.ICONINFO iconInfo;
if (!Win32Stuff.GetIconInfo(hicon, out iconInfo))
{
return null;
} x = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot);
y = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot); using (Bitmap maskBitmap = Bitmap.FromHbitmap(iconInfo.hbmMask))
{
// Is this a monochrome cursor?
if (maskBitmap.Height == maskBitmap.Width * )
{
Bitmap resultBitmap = new Bitmap(maskBitmap.Width, maskBitmap.Width); using (Graphics desktopGraphics = Graphics.FromHwnd(Win32Stuff.GetDesktopWindow()))
{
IntPtr desktopHdc = desktopGraphics.GetHdc(); IntPtr maskHdc = GDIStuff.CreateCompatibleDC(desktopHdc);
IntPtr oldPtr = GDIStuff.SelectObject(maskHdc, maskBitmap.GetHbitmap()); using (Graphics resultGraphics = Graphics.FromImage(resultBitmap))
{
IntPtr resultHdc = resultGraphics.GetHdc(); // These two operation will result in a black cursor over a white background.
// Later in the code, a call to MakeTransparent() will get rid of the white background.
GDIStuff.BitBlt(
resultHdc,
,
,
,
,
maskHdc,
,
,
(int)GDIStuff.TernaryRasterOperations.SRCCOPY);
GDIStuff.BitBlt(
resultHdc,
,
,
,
,
maskHdc,
,
,
(int)GDIStuff.TernaryRasterOperations.SRCINVERT); resultGraphics.ReleaseHdc(resultHdc);
GDIStuff.DeleteDC(resultHdc);
GDIStuff.DeleteObject(resultHdc);
} IntPtr newPtr = GDIStuff.SelectObject(maskHdc, oldPtr);
GDIStuff.DeleteObject(oldPtr);
GDIStuff.DeleteObject(newPtr);
GDIStuff.DeleteDC(maskHdc);
desktopGraphics.ReleaseHdc(desktopHdc);
GDIStuff.DeleteDC(desktopHdc);
} // Remove the white background from the BitBlt calls,
// resulting in a black cursor over a transparent background.
resultBitmap.MakeTransparent(Color.White);
return resultBitmap;
}
} //// Delete the mask, if present.
// if (iconInfo.hbmMask != IntPtr.Zero)
// {
// DeleteObject(iconInfo.hbmMask);
// } //// Delete the color bitmap, if present.
// if (iconInfo.hbmColor != IntPtr.Zero)
// {
// DeleteObject(iconInfo.hbmColor);
// }
using (Icon icon = Icon.FromHandle(hicon))
{
return icon.ToBitmap();
}
} #endregion #region Methods /// <summary>
/// The copy icon.
/// </summary>
/// <param name="hIcon">
/// The h icon.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("user32.dll")]
private static extern IntPtr CopyIcon(IntPtr hIcon); /// <summary>
/// The delete object.
/// </summary>
/// <param name="hDc">
/// The h dc.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("gdi32.dll")]
private static extern IntPtr DeleteObject(IntPtr hDc); /// <summary>
/// The destroy icon.
/// </summary>
/// <param name="hIcon">
/// The h icon.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
[DllImport("user32.dll")]
private static extern bool DestroyIcon(IntPtr hIcon); /// <summary>
/// The get cursor info.
/// </summary>
/// <param name="pci">
/// The pci.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
[DllImport("user32.dll")]
private static extern bool GetCursorInfo(out CURSORINFO pci); /// <summary>
/// The get gdi handle count.
/// </summary>
/// <returns>
/// The <see cref="int" />.
/// </returns>
private static int GetGDIHandleCount()
{
return GetGuiResources(Process.GetCurrentProcess().Handle, );
} /// <summary>
/// The get gui resources.
/// </summary>
/// <param name="hProcess">
/// The h process.
/// </param>
/// <param name="uiFlags">
/// The ui flags.
/// </param>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
[DllImport("user32.dll")]
private static extern int GetGuiResources(IntPtr hProcess, int uiFlags); /// <summary>
/// The get icon info.
/// </summary>
/// <param name="hIcon">
/// The h icon.
/// </param>
/// <param name="piconinfo">
/// The piconinfo.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
[DllImport("user32.dll")]
private static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo); /// <summary>
/// The get user handle count.
/// </summary>
/// <returns>
/// The <see cref="int" />.
/// </returns>
private static int GetUserHandleCount()
{
return GetGuiResources(Process.GetCurrentProcess().Handle, );
} /// <summary>
/// The handle message.
/// </summary>
/// <param name="message">
/// The message.
/// </param>
private static void HandleMessage(string message)
{
Debug.WriteLine("HC: " + message + ": GDI: " + GetGDIHandleCount() + ": User: " + GetUserHandleCount());
} #endregion /// <summary>
/// The cursorinfo.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct CURSORINFO
{
// Fields
/// <summary>
/// The cb size.
/// </summary>
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."),
SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
public int cbSize; /// <summary>
/// The flags.
/// </summary>
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."),
SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
public int flags; /// <summary>
/// The h cursor.
/// </summary>
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."),
SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
public IntPtr hCursor; /// <summary>
/// The pt screen pos.
/// </summary>
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."),
SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
public POINT ptScreenPos;
} /// <summary>
/// The iconinfo.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct ICONINFO
{
// Fields
/// <summary>
/// The f icon.
/// </summary>
public bool fIcon; /// <summary>
/// The x hotspot.
/// </summary>
public int xHotspot; /// <summary>
/// The y hotspot.
/// </summary>
public int yHotspot; // Handle of the icon’s bitmask bitmap.
/// <summary>
/// The hbm mask.
/// </summary>
public IntPtr hbmMask; // Handle of the icon’s color bitmap. Optional for monochrome icons.
/// <summary>
/// The hbm color.
/// </summary>
public IntPtr hbmColor;
} /// <summary>
/// The point.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
// Fields
/// <summary>
/// The x.
/// </summary>
public int x; /// <summary>
/// The y.
/// </summary>
public int y;
} ///// <summary>
///// The capture cursor.
///// </summary>
///// <param name="x">
///// The x.
///// </param>
///// <param name="y">
///// The y.
///// </param>
///// <returns>
///// The <see cref="Bitmap"/>.
///// </returns>
// public static Bitmap CaptureCursor(ref int x, ref int y)
// {
// try
// {
// // Return value initially nothing
// Bitmap bmp = null; // CURSORINFO curInfo = new CURSORINFO();
// curInfo.cbSize = Marshal.SizeOf(curInfo); // // HandleMessage("Start")
// if (GetCursorInfo(ref curInfo))
// {
// if (curInfo.flags == CURSOR_SHOWING)
// {
// IntPtr hicon = CopyIcon(curInfo.hCursor); // if (hicon != IntPtr.Zero)
// {
// ICONINFO icoInfo = default(ICONINFO);
// if (GetIconInfo(hicon, ref icoInfo))
// {
// // Delete the mask, if present.
// if (icoInfo.hbmMask != IntPtr.Zero)
// {
// DeleteObject(icoInfo.hbmMask);
// } // // Delete the color bitmap, if present.
// if (icoInfo.hbmColor != IntPtr.Zero)
// {
// DeleteObject(icoInfo.hbmColor);
// } // x = curInfo.ptScreenPos.x - icoInfo.xHotspot;
// y = curInfo.ptScreenPos.y - icoInfo.yHotspot;
// } // Icon ic = Icon.FromHandle(hicon);
// bmp = ic.ToBitmap(); // // Must destroy the icon object we got from CopyIcon
// DestroyIcon(hicon);
// }
// }
// } // // HandleMessage("End")
// return bmp;
// }
// catch
// {
// return null;
// }
// }
}

CursorHelper.cs

    /// <summary>
/// The gdi stuff.
/// </summary>
internal class GDIStuff
{
#region Constants /// <summary>
/// The srccopy.
/// </summary>
public const int SRCCOPY = ; #endregion #region Enums /// <summary>
/// Specifies a raster-operation code. These codes define how the color data for the
/// source rectangle is to be combined with the color data for the destination
/// rectangle to achieve the final color.
/// </summary>
public enum TernaryRasterOperations
{
/// <summary>dest = source</summary>
SRCCOPY = 0x00CC0020, /// <summary>dest = source OR dest</summary>
SRCPAINT = 0x00EE0086, /// <summary>dest = source AND dest</summary>
SRCAND = 0x008800C6, /// <summary>dest = source XOR dest</summary>
SRCINVERT = 0x00660046, /// <summary>dest = source AND (NOT dest)</summary>
SRCERASE = 0x00440328, /// <summary>dest = (NOT source)</summary>
NOTSRCCOPY = 0x00330008, /// <summary>dest = (NOT src) AND (NOT dest)</summary>
NOTSRCERASE = 0x001100A6, /// <summary>dest = (source AND pattern)</summary>
MERGECOPY = 0x00C000CA, /// <summary>dest = (NOT source) OR dest</summary>
MERGEPAINT = 0x00BB0226, /// <summary>dest = pattern</summary>
PATCOPY = 0x00F00021, /// <summary>dest = DPSnoo</summary>
PATPAINT = 0x00FB0A09, /// <summary>dest = pattern XOR dest</summary>
PATINVERT = 0x005A0049, /// <summary>dest = (NOT dest)</summary>
DSTINVERT = 0x00550009, /// <summary>dest = BLACK</summary>
BLACKNESS = 0x00000042, /// <summary>dest = WHITE</summary>
WHITENESS = 0x00FF0062, /// <summary>
/// Capture window as seen on screen. This includes layered windows
/// such as WPF windows with AllowsTransparency="true"
/// </summary>
CAPTUREBLT = 0x40000000
} #endregion #region Public Methods and Operators /// <summary>
/// The bit blt.
/// </summary>
/// <param name="hdcDest">
/// The hdc dest.
/// </param>
/// <param name="xDest">
/// The x dest.
/// </param>
/// <param name="yDest">
/// The y dest.
/// </param>
/// <param name="wDest">
/// The w dest.
/// </param>
/// <param name="hDest">
/// The h dest.
/// </param>
/// <param name="hdcSource">
/// The hdc source.
/// </param>
/// <param name="xSrc">
/// The x src.
/// </param>
/// <param name="ySrc">
/// The y src.
/// </param>
/// <param name="RasterOp">
/// The raster op.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here.")]
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:FieldNamesMustBeginWithLowerCaseLetter", Justification = "Reviewed. Suppression is OK here.")]
public static extern bool BitBlt(
IntPtr hdcDest,
int xDest,
int yDest,
int wDest,
int hDest,
IntPtr hdcSource,
int xSrc,
int ySrc,
int RasterOp); /// <summary>
/// The create compatible bitmap.
/// </summary>
/// <param name="hdc">
/// The hdc.
/// </param>
/// <param name="nWidth">
/// The n width.
/// </param>
/// <param name="nHeight">
/// The n height.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")]
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here.")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); /// <summary>
/// The create compatible dc.
/// </summary>
/// <param name="hdc">
/// The hdc.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc); /// <summary>
/// The create dc.
/// </summary>
/// <param name="lpszDriver">
/// The lpsz driver.
/// </param>
/// <param name="lpszDevice">
/// The lpsz device.
/// </param>
/// <param name="lpszOutput">
/// The lpsz output.
/// </param>
/// <param name="lpInitData">
/// The lp init data.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("gdi32.dll", EntryPoint = "CreateDC")]
public static extern IntPtr CreateDC(IntPtr lpszDriver, string lpszDevice, IntPtr lpszOutput, IntPtr lpInitData); /// <summary>
/// The delete dc.
/// </summary>
/// <param name="hDc">
/// The h dc.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
public static extern IntPtr DeleteDC(IntPtr hDc); /// <summary>
/// The delete object.
/// </summary>
/// <param name="hDc">
/// The h dc.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
public static extern IntPtr DeleteObject(IntPtr hDc); /// <summary>
/// The select object.
/// </summary>
/// <param name="hdc">
/// The hdc.
/// </param>
/// <param name="bmp">
/// The bmp.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("gdi32.dll", EntryPoint = "SelectObject")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp); #endregion
}

GDIStuff.cs

 /// <summary>
/// The win 32 stuff.
/// </summary>
internal class Win32Stuff
{
#region Constants /// <summary>
/// The curso r_ showing.
/// </summary>
public const int CURSOR_SHOWING = 0x00000001; /// <summary>
/// The s m_ cxscreen.
/// </summary>
public const int SM_CXSCREEN = ; /// <summary>
/// The s m_ cyscreen.
/// </summary>
public const int SM_CYSCREEN = ; #endregion #region Public Methods and Operators /// <summary>
/// The copy icon.
/// </summary>
/// <param name="hIcon">
/// The h icon.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("user32.dll", EntryPoint = "CopyIcon")]
public static extern IntPtr CopyIcon(IntPtr hIcon); /// <summary>
/// The get cursor info.
/// </summary>
/// <param name="pci">
/// The pci.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
[DllImport("user32.dll", EntryPoint = "GetCursorInfo")]
public static extern bool GetCursorInfo(out CURSORINFO pci); /// <summary>
/// The get dc.
/// </summary>
/// <param name="ptr">
/// The ptr.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("user32.dll", EntryPoint = "GetDC")]
public static extern IntPtr GetDC(IntPtr ptr); /// <summary>
/// The get desktop window.
/// </summary>
/// <returns>
/// The <see cref="IntPtr" />.
/// </returns>
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
public static extern IntPtr GetDesktopWindow(); /// <summary>
/// The get icon info.
/// </summary>
/// <param name="hIcon">
/// The h icon.
/// </param>
/// <param name="piconinfo">
/// The piconinfo.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
[DllImport("user32.dll", EntryPoint = "GetIconInfo")]
public static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo); /// <summary>
/// The get system metrics.
/// </summary>
/// <param name="abc">
/// The abc.
/// </param>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
[DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
public static extern int GetSystemMetrics(int abc); /// <summary>
/// The get window dc.
/// </summary>
/// <param name="ptr">
/// The ptr.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("user32.dll", EntryPoint = "GetWindowDC")]
public static extern IntPtr GetWindowDC(int ptr); /// <summary>
/// The release dc.
/// </summary>
/// <param name="hWnd">
/// The h wnd.
/// </param>
/// <param name="hDc">
/// The h dc.
/// </param>
/// <returns>
/// The <see cref="IntPtr"/>.
/// </returns>
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc); #endregion /// <summary>
/// The cursorinfo.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct CURSORINFO
{
/// <summary>
/// The cb size.
/// </summary>
public int cbSize; // Specifies the size, in bytes, of the structure. /// <summary>
/// The flags.
/// </summary>
public int flags; // Specifies the cursor state. This parameter can be one of the following values: /// <summary>
/// The h cursor.
/// </summary>
public IntPtr hCursor; // Handle to the cursor. /// <summary>
/// The pt screen pos.
/// </summary>
public POINT ptScreenPos; // A POINT structure that receives the screen coordinates of the cursor.
} /// <summary>
/// The iconinfo.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ICONINFO
{
/// <summary>
/// The f icon.
/// </summary>
public bool fIcon; // Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies /// <summary>
/// The x hotspot.
/// </summary>
public int xHotspot; // Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot /// <summary>
/// The y hotspot.
/// </summary>
public int yHotspot; // Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot /// <summary>
/// The hbm mask.
/// </summary>
public IntPtr hbmMask; // (HBITMAP) Specifies the icon bitmask bitmap. If this structure defines a black and white icon, /// <summary>
/// The hbm color.
/// </summary>
public IntPtr hbmColor; // (HBITMAP) Handle to the icon color bitmap. This member can be optional if this
} /// <summary>
/// The point.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
/// <summary>
/// The x.
/// </summary>
public int x; /// <summary>
/// The y.
/// </summary>
public int y;
}
}

Win32Stuff.cs

OK,类已经铺垫好了,接下来就在你的视频捕获方法中放入:关键方法--CursorHelper.CaptureCursor(ref x,ref y);

                                        Graphics g = Graphics.FromImage(bitmap);//编辑原始视频帧
g.SmoothingMode = SmoothingMode.AntiAlias;//设置鼠标质量
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
var x = _currentPoint.X;
var y = _currentPoint.Y;
var cursorBmp = CursorHelper.CaptureCursor(ref x, ref y);
if (cursorBmp != null)
{
g.DrawImage(cursorBmp, _currentPoint);
}
cursorBmp.Dispose();

**注释说明:其中_currentPoint 是相对于屏幕的坐标Point** 获取方法是--

 _currentPoint = System.Windows.Forms.Cursor.Position;//(大屏坐标)

**注释说明:其中bitmap是当前获取的最原始的视频帧(不包含任何的例如光标-声音-什么锤子之类的哈哈哈)**,此类方法就是把原始视频帧重新编辑!

第二种方式:相对简单一点,获取光标_currentPoint还是使用上面的方法,但是不同的地方是我要自定义光标icon,这个又有一点难点就是如何画怎么画;---项目中采用的是外圈描边,内边填充方式;

  SolidBrush myBrush = new SolidBrush(System.Drawing.Color.FromArgb(, ColorTranslator.FromHtml("#你的填充颜色")));//设置透明度跟填充颜色
System.Drawing.Pen p = new System.Drawing.Pen(ColorTranslator.FromHtml("#你的描边颜色"));//设置透明度跟描边颜色
Graphics g = Graphics.FromImage(bitmap);//编辑原始视频帧
g.SmoothingMode = SmoothingMode.AntiAlias;//设置鼠标质量
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawEllipse(p, new Rectangle(_currentPoint.X - this.screenArea.Left, _currentPoint.Y - this.screenArea.Top, , ));//描边
g.FillEllipse(myBrush, new Rectangle(_currentPoint.X - this.screenArea.Left, _currentPoint.Y - this.screenArea.Top, , ));//填充圆形区域
myBrush.Dispose();
p.Dispose();
g.Flush();

**注释:在上述这种方式中特别注意,原始的方法比如你是全屏录制则采用以下方式即可,还有自定义笔刷的画法,我想做完给大家分享。**

                                        g.DrawEllipse(p, new Rectangle(_currentPoint.X , _currentPoint.Y, , ));//描边
g.FillEllipse(myBrush, new Rectangle(_currentPoint.X , _currentPoint.Y, , ));//填充圆形区域

**注释:如果你的录屏方式也存在区域模式,那么就采用 当前光标位置X轴减去你录屏区域的左坐标,当前光标位置Y轴减去你录屏的顶坐标即可获取,这种方式自适应任何区域**

以上是个人在完善时候研究的成果,在此希望把它们分享给更多正在研究的伙伴们,因为研究的时候的确遇到了非常多的问题,我希望这些文章能够给你们一些方向研究,加快你们的开发进度。

C# 全屏坐标及区域坐标获取。自定义光标及系统光标描边捕捉显示。的更多相关文章

  1. ios滑动手势全屏(这段代码实现了下一级控制器滑到上一级控制器)

    在自定义导航控制器里面加以下代码就增加全屏滑动手势 >推向前一个控制器 //  HBNavigationController.m // #import "HBNavigationCon ...

  2. iOS开发——实用技术OC篇&8行代码教你搞定导航控制器全屏滑动返回效果

    8行代码教你搞定导航控制器全屏滑动返回效果 前言 如果自定了导航控制器的自控制器的leftBarButtonItem,可能会引发边缘滑动pop效果的失灵,是由于 self.interactivePop ...

  3. WebView中的视频全屏的相关操作

    近期工作中,基本一直在用WebView,今天就把它整理下: WebView 顾名思义,就是放一个网页,一个看起来十分简单,可是用起来不是那么简单的控件. 首先你肯定要定义,初始化一个webview,事 ...

  4. Bootstrap全屏

    1.由于bootstrap中的.containter是根据媒体查询定死了width,所以页面不会占满全屏,若要全屏,则最外面的div的class不能用container(或改用.container-f ...

  5. QT 子窗口退出全屏

    m_pWidget代表子窗口, 子窗口显示全屏: m_pWidget->setWindowFlags(Qt::Dialog); m_pWidget->showFullScreen(); 子 ...

  6. C# WinForm 关于窗体最大化时的是否全屏效果与是否遮盖任务栏

    0.新建窗体 及添加按钮 1.  执行如下按钮事件  private void btnFormMax_Click(object sender, EventArgs e)  {     if (this ...

  7. VMware全屏时, 隐藏上方工具栏横条

    VMware全屏时, 隐藏上方横条 菜单栏打开 编辑 选择 首选项 找到 显示 取消勾选 在全屏时取消固定时显示工具栏边缘

  8. 全屏API

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=2679 二.相关文章以 ...

  9. iOS端一次视频全屏需求的实现(转)

    对于一个带有视频播放功能的app产品来说,视频全屏是一个基本且重要的需求.虽然这个需求看起来很简单,但是在实现上,我们前后迭代了三套技术方案.这篇文章将介绍这三种实现方案中的利弊和坑点,以及实现过程中 ...

随机推荐

  1. 配置文件读取工具类--PropertiesUtil

    /** * 属性工具类 * @author admin * 参考:https://www.cnblogs.com/doudouxiaoye/p/5693454.html */ public class ...

  2. systemd 和 如何修改和创建一个 systemd service (Understanding and administering systemd)

    系统中经常会使用到 systemctl 去管理systemd程序,刚刚看了一篇关于 systemd 和 SysV 相关的文章,这里简要记录一下: systemd定义: (英文来解释更为原汁原味) sy ...

  3. Jquery获取当前页面中的复选框选中的内容

    在使用$.post提交数据时,有一个数据是复选框获取数据,所以在当前页面获取到复选框选中的值并提交到后端卡住了一下,解决方法如下: 这两个input就是复选框的内容: str += "< ...

  4. Win7系统system进程句柄数一直增加解决方案

    公司内部最近有个服务端的同事电脑句柄数一开机就一直增加 一台Windows7x64系统16G 其实物理内存使用情况在开机后并没有太大的变化,但虚拟内存占用明显在不停的增加. 我通过“任务管理器”一直也 ...

  5. python最全学习资料:python基础进阶+人工智能+机器学习+神经网络(包括黑马程序员2017年12月python视频(百度云链接))

    首先用数据说话,看看资料大小,达到675G 承诺:真实资料.不加密,获取资料请加QQ:122317653 包含内容:1.python基础+进阶+应用项目实战 2.神经网络算法+python应用 3.人 ...

  6. 如何创建一个 mongo 数据库并为它添加一个认证用户?

    0.登录 admin 库,开启一个 mongo shell mongo --port 27017 -u "adminUser" -p "adminPass" - ...

  7. 跨域访问的解决方案(非HTML5的方法:JSONP)

    http://supercharles888.blog.51cto.com/609344/856886 跨域访问一直是困扰很多开发者的问题之一.因为涉及到安全性问题,所以跨域访问默认是不可以进行的,否 ...

  8. <20180923>中秋节日期间的维护日志

    (一) 陌生环境下断网是有风险的,提前做好准备. 1.1 某企业的机柜自2017年5月开始就没有作硬件更新和维护了: 趁着这次节日空挡可做一个机柜的重新整理维护: 首先看了下是老款某知名品牌的型号为6 ...

  9. nodejs中async使用

    waterfall , parallel ,  series  ,  eachSeries //var async = require('async'); /*** *① * 串行有关联 执行每个函数 ...

  10. log4j2 yml

    1.log4j2默认加载文件为log4j2.xml 2.要使用yml加载需添加依赖 <!-- https://mvnrepository.com/artifact/com.fasterxml.j ...