如何只捕获屏幕上鼠标点击的区域?
How capture only the region of mouse click on screen?
每次单击鼠标左键时,以下代码都会对桌面进行屏幕截图。
但是我想只对发生鼠标点击的区域进行截图,例如,如果在某个网站上点击了某个按钮,则截图只能是这个按钮。
GIF
这可能吗?
如果是,如果有人展示代码示例,我将非常高兴!提前致谢。
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows,
Messages,
SysUtils,
Graphics,
Imaging.PngImage;
type
MouseLLHookStruct = record
end;
const
WH_MOUSE_LL = 14;
var
Msg: TMsg;
mHook: Cardinal;
procedure GetCursor(ScreenShotBitmap: TBitmap);
var
R: TRect;
Icon: TIcon;
II: TIconInfo;
CI: TCursorInfo;
begin
R := ScreenShotBitmap.Canvas.ClipRect;
Icon := TIcon.Create;
try
CI.cbSize := SizeOf(CI);
if GetCursorInfo(CI) then
if CI.Flags = CURSOR_SHOWING then
begin
Icon.Handle := CopyIcon(CI.hCursor);
if GetIconInfo(Icon.Handle, II) then
begin
ScreenShotBitmap.Canvas.Draw(CI.ptScreenPos.X - Integer(II.xHotspot) -
R.Left, CI.ptScreenPos.Y - Integer(II.yHotspot) - R.Top, Icon);
end;
end;
finally
Icon.Free;
end;
end;
procedure ScreenCapture;
var
DC: HDC;
Rect: TRect;
png: TPngImage;
Bitmap: TBitmap;
begin
png := TPngImage.Create;
Bitmap := TBitmap.Create;
GetWindowRect(GetDesktopWindow, Rect);
DC := GetWindowDC(GetDesktopWindow);
try
Bitmap.Width := Rect.Right - Rect.Left;
Bitmap.Height := Rect.Bottom - Rect.Top;
BitBlt(Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, DC, 0,
0, SRCCOPY);
GetCursor(Bitmap);
png.Assign(Bitmap);
png.SaveToFile('screenshot.png');
finally
ReleaseDC(GetDesktopWindow, DC);
png.Free;
Bitmap.Free;
end;
end;
function LowLevelMouseHookProc(nCode: LongInt; WPARAM: WPARAM; lParam: lParam)
: LRESULT; stdcall;
var
info: ^MouseLLHookStruct absolute lParam;
begin
Result := CallNextHookEx(mHook, nCode, WPARAM, lParam);
if (WPARAM = WM_LBUTTONUP) then
ScreenCapture;
end;
begin
mHook := SetWindowsHookEx(WH_MOUSE_LL, @LowLevelMouseHookProc, HInstance, 0);
while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
UnhookWindowsHookEx(mHook);
end.
编辑:
我在 VB.NET 中找到了替代方案。但是 Delphi 代码如何解决?
Private Shared Function CaptureCursor(ByRef x As Integer, ByRef y As Integer) As Bitmap
Dim bmp As Bitmap
Dim hicon As IntPtr
Dim ci As New CURSORINFO()
Dim icInfo As ICONINFO
ci.cbSize = Marshal.SizeOf(ci)
If GetCursorInfo(ci) Then
hicon = CopyIcon(ci.hCursor)
If GetIconInfo(hicon, icInfo) Then
x = ci.ptScreenPos.X - CInt(icInfo.xHotspot)
y = ci.ptScreenPos.Y - CInt(icInfo.yHotspot)
Dim ic As Icon = Icon.FromHandle(hicon)
bmp = ic.ToBitmap()
ic.Dispose()
Return bmp
End If
End If
Return Nothing
End Function
'Insert on Timer tick event
Private Sub Screenshot()
Dim x As Integer
Dim y As Integer
Dim cursorBmp As Bitmap = CaptureCursor(x, y)
Dim bmp As New Bitmap(Cursor.Size.Width, Cursor.Size.Height)
Dim sourceLocation As Point = Control.MousePosition
sourceLocation.Offset(-16, -16)
Using g As Graphics = Graphics.FromImage(bmp)
g.CopyFromScreen(sourceLocation, Point.Empty, bmp.Size)
g.DrawImage(cursorBmp, x - sourceLocation.X, y - sourceLocation.Y)
cursorBmp.Dispose()
End Using
Me.PictureBox1.Image = bmp
End Sub
有一个简单的方法,可以参考这篇thread,
中的代码
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows, Graphics;
procedure DrawCursor (ACanvas:TCanvas; Position:TPoint) ;
var
HCursor : THandle;
begin
HCursor := GetCursor;
DrawIconEx(ACanvas.Handle, Position.X, Position.Y,
HCursor, 32, 32, 0, 0, DI_NORMAL) ;
end;
function CaptureWindow(const WindowHandle: HWnd): TBitmap;
var
DC: HDC;
wRect: TRect;
CurPos: TPoint;
begin
DC := GetWindowDC(WindowHandle);
Result := TBitmap.Create;
try
GetWindowRect(WindowHandle, wRect);
Result.Width := wRect.Right - wRect.Left;
Result.Height := wRect.Bottom - wRect.Top;
BitBlt(Result.Canvas.Handle,
0,
0,
Result.Width,
Result.Height,
DC,
0,
0,
SRCCOPY);
GetCursorPos(CurPos);
DrawCursor(Result.Canvas, CurPos);
finally
ReleaseDC(WindowHandle, DC);
end;
end;
// Sample usage starts here
var
Bmp: TBitmap;
begin
Bmp := CaptureWindow(GetDesktopWindow);
Bmp.SaveToFile('D:\TempFiles\FullScreenCap.bmp');
Bmp.Free;
WriteLn('Screen captured.');
ReadLn;
end.
这段代码可以获取包含鼠标位置的屏幕截图,只需使用BitBlt
指定鼠标坐标和矩形大小(按钮大小),最终得到您需要的BMP图片。使用DrawImage
将BMP图片绘制成矩形框,如图GIF所示。
鼠标坐标可以通过调用GetCursorInfo
获取,矩形的大小可以根据需要指定。
注意,有了鼠标坐标后,传入BitBlt
时需要分别减去左边和上面半个矩形的大小。
例如,
BitBlt(Newhdc,
0,
0,
rect_x, //size of the rect
rect_y,
HDC,
x - half_rect_x, //x,y => mouse coordinates
y - half_rect_y, //half_rect_x, half_rect_y => the size of half the rectangle
SRCCOPY);
每次单击鼠标左键时,以下代码都会对桌面进行屏幕截图。 但是我想只对发生鼠标点击的区域进行截图,例如,如果在某个网站上点击了某个按钮,则截图只能是这个按钮。
GIF
这可能吗?
如果是,如果有人展示代码示例,我将非常高兴!提前致谢。
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows,
Messages,
SysUtils,
Graphics,
Imaging.PngImage;
type
MouseLLHookStruct = record
end;
const
WH_MOUSE_LL = 14;
var
Msg: TMsg;
mHook: Cardinal;
procedure GetCursor(ScreenShotBitmap: TBitmap);
var
R: TRect;
Icon: TIcon;
II: TIconInfo;
CI: TCursorInfo;
begin
R := ScreenShotBitmap.Canvas.ClipRect;
Icon := TIcon.Create;
try
CI.cbSize := SizeOf(CI);
if GetCursorInfo(CI) then
if CI.Flags = CURSOR_SHOWING then
begin
Icon.Handle := CopyIcon(CI.hCursor);
if GetIconInfo(Icon.Handle, II) then
begin
ScreenShotBitmap.Canvas.Draw(CI.ptScreenPos.X - Integer(II.xHotspot) -
R.Left, CI.ptScreenPos.Y - Integer(II.yHotspot) - R.Top, Icon);
end;
end;
finally
Icon.Free;
end;
end;
procedure ScreenCapture;
var
DC: HDC;
Rect: TRect;
png: TPngImage;
Bitmap: TBitmap;
begin
png := TPngImage.Create;
Bitmap := TBitmap.Create;
GetWindowRect(GetDesktopWindow, Rect);
DC := GetWindowDC(GetDesktopWindow);
try
Bitmap.Width := Rect.Right - Rect.Left;
Bitmap.Height := Rect.Bottom - Rect.Top;
BitBlt(Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, DC, 0,
0, SRCCOPY);
GetCursor(Bitmap);
png.Assign(Bitmap);
png.SaveToFile('screenshot.png');
finally
ReleaseDC(GetDesktopWindow, DC);
png.Free;
Bitmap.Free;
end;
end;
function LowLevelMouseHookProc(nCode: LongInt; WPARAM: WPARAM; lParam: lParam)
: LRESULT; stdcall;
var
info: ^MouseLLHookStruct absolute lParam;
begin
Result := CallNextHookEx(mHook, nCode, WPARAM, lParam);
if (WPARAM = WM_LBUTTONUP) then
ScreenCapture;
end;
begin
mHook := SetWindowsHookEx(WH_MOUSE_LL, @LowLevelMouseHookProc, HInstance, 0);
while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
UnhookWindowsHookEx(mHook);
end.
编辑:
我在 VB.NET 中找到了替代方案。但是 Delphi 代码如何解决?
Private Shared Function CaptureCursor(ByRef x As Integer, ByRef y As Integer) As Bitmap
Dim bmp As Bitmap
Dim hicon As IntPtr
Dim ci As New CURSORINFO()
Dim icInfo As ICONINFO
ci.cbSize = Marshal.SizeOf(ci)
If GetCursorInfo(ci) Then
hicon = CopyIcon(ci.hCursor)
If GetIconInfo(hicon, icInfo) Then
x = ci.ptScreenPos.X - CInt(icInfo.xHotspot)
y = ci.ptScreenPos.Y - CInt(icInfo.yHotspot)
Dim ic As Icon = Icon.FromHandle(hicon)
bmp = ic.ToBitmap()
ic.Dispose()
Return bmp
End If
End If
Return Nothing
End Function
'Insert on Timer tick event
Private Sub Screenshot()
Dim x As Integer
Dim y As Integer
Dim cursorBmp As Bitmap = CaptureCursor(x, y)
Dim bmp As New Bitmap(Cursor.Size.Width, Cursor.Size.Height)
Dim sourceLocation As Point = Control.MousePosition
sourceLocation.Offset(-16, -16)
Using g As Graphics = Graphics.FromImage(bmp)
g.CopyFromScreen(sourceLocation, Point.Empty, bmp.Size)
g.DrawImage(cursorBmp, x - sourceLocation.X, y - sourceLocation.Y)
cursorBmp.Dispose()
End Using
Me.PictureBox1.Image = bmp
End Sub
有一个简单的方法,可以参考这篇thread,
中的代码program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows, Graphics;
procedure DrawCursor (ACanvas:TCanvas; Position:TPoint) ;
var
HCursor : THandle;
begin
HCursor := GetCursor;
DrawIconEx(ACanvas.Handle, Position.X, Position.Y,
HCursor, 32, 32, 0, 0, DI_NORMAL) ;
end;
function CaptureWindow(const WindowHandle: HWnd): TBitmap;
var
DC: HDC;
wRect: TRect;
CurPos: TPoint;
begin
DC := GetWindowDC(WindowHandle);
Result := TBitmap.Create;
try
GetWindowRect(WindowHandle, wRect);
Result.Width := wRect.Right - wRect.Left;
Result.Height := wRect.Bottom - wRect.Top;
BitBlt(Result.Canvas.Handle,
0,
0,
Result.Width,
Result.Height,
DC,
0,
0,
SRCCOPY);
GetCursorPos(CurPos);
DrawCursor(Result.Canvas, CurPos);
finally
ReleaseDC(WindowHandle, DC);
end;
end;
// Sample usage starts here
var
Bmp: TBitmap;
begin
Bmp := CaptureWindow(GetDesktopWindow);
Bmp.SaveToFile('D:\TempFiles\FullScreenCap.bmp');
Bmp.Free;
WriteLn('Screen captured.');
ReadLn;
end.
这段代码可以获取包含鼠标位置的屏幕截图,只需使用BitBlt
指定鼠标坐标和矩形大小(按钮大小),最终得到您需要的BMP图片。使用DrawImage
将BMP图片绘制成矩形框,如图GIF所示。
鼠标坐标可以通过调用GetCursorInfo
获取,矩形的大小可以根据需要指定。
注意,有了鼠标坐标后,传入BitBlt
时需要分别减去左边和上面半个矩形的大小。
例如,
BitBlt(Newhdc,
0,
0,
rect_x, //size of the rect
rect_y,
HDC,
x - half_rect_x, //x,y => mouse coordinates
y - half_rect_y, //half_rect_x, half_rect_y => the size of half the rectangle
SRCCOPY);