c# wpf 利用截屏键实现截屏功能
最近做一个wpf程序需要截图功能,查找资料费了一些曲折,跟大家分享一下。
先是找到了这样一份代码:
static class ScreenCut
{
public static System.Drawing.Bitmap GetScreenSnapshot()
{
System.Drawing.Rectangle rc = System.Windows.Forms.SystemInformation.VirtualScreen;
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap))
{
g.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, System.Drawing.CopyPixelOperation.SourceCopy);
}
return bitmap;
}
public static BitmapSource ToBitmapSource(this System.Drawing.Bitmap bmp)
{
BitmapSource returnSource;
try
{
returnSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
catch
{
returnSource = null;
}
return returnSource;
}
public static BitmapSource CopyFromScreenSnapshot(BitmapSource screenSnapshot, Rect region)
{
var sourceRect = new System.Drawing.Rectangle((int)region.Left, (int)region.Top, (int)region.Width, (int)region.Height);
var destRect = new System.Drawing.Rectangle(0, 0, sourceRect.Width, sourceRect.Height);
if (screenSnapshot != null)
{
var bitmap = new System.Drawing.Bitmap(sourceRect.Width, sourceRect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap))
{
g.DrawImage(bitmap, destRect, sourceRect.Left, sourceRect.Top, sourceRect.Width, sourceRect.Height, System.Drawing.GraphicsUnit.Pixel);
}
return bitmap.ToBitmapSource();
}
return null;
}
}
调用时包装一下,下面的函数截下屏幕指定区域并保存:
System.Drawing.Image takePicture(Rect wnd, String saveLocation, String pictureName)
{
BitmapSource bitmapScr = ScreenCut.CopyFromScreenSnapshot(ScreenCut.ToBitmapSource(ScreenCut.GetScreenSnapshot()),wnd);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapScr));
FileStream fileStream = new FileStream(saveLocation + "\\" + pictureName ".png", FileMode.Create, FileAccess.Write);
encoder.Save(fileStream);
fileStream.Close();
}
但实际效果保存下来的图是空的,经验证前两个函数没有问题。于是我查资料找到了另一种切割BitmapSource的方法,将第三个函数改成这样:
BitmapSource CopyFromScreenSnapshot(BitmapSource screenSnapshot, Rect region)
{
Int32Rect window = new Int32Rect(region.X, region.Y, region.Width, region.Height);
BitmapSource bitmapScr = ScreenCut.ToBitmapSource(ScreenCut.GetScreenSnapshot());
//计算Stride
int stride = bitmapScr.Format.BitsPerPixel * window.Width / 8;
//声明字节数组
byte[] data = new byte[window.Height * stride];
//调用CopyPixels
bitmapScr.CopyPixels(window, data, stride, 0);
PngBitmapEncoder encoder = new PngBitmapEncoder();
return BitmapSource.Create(window.Width, window.Height, 0, 0, PixelFormats.Bgr32, null, data, stride);
}
这样总算能截到屏了。不过后来发现在某些主题下有些程序的窗口在截下的图中是透明的。这个方法还是不够完美。
我想到了利用键盘的截屏键截图再进行剪切的方法。分为三步:1、模拟按下截屏键 2、从剪贴板获取图片 3、截取和保存图片。
对于第一点,利用SendMessage函数发送WM_KEY事件没有用,不过我找到了另一个模拟键盘输入的方法:
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
static extern void keybd_event
(
byte bVk,// 虚拟键值
byte bScan,// 硬件扫描码
uint dwFlags,// 动作标识
IntPtr dwExtraInfo// 与键盘动作关联的辅加信息
);
上面这个函数对本程序发送按钮事件,模拟截屏键的话像下面这样写,wpf需要在项目添加引用System.Windows.Forms
const int VK_SNAPSHOT = 0x2C;
public void PrintScreen()
{
keybd_event((byte)VK_SNAPSHOT, 0, 0x0, IntPtr.Zero);//down
System.Windows.Forms.Application.DoEvents();//强制窗口响应按钮事件
keybd_event((byte)VK_SNAPSHOT, 0, 0x2, IntPtr.Zero);//up
System.Windows.Forms.Application.DoEvents();
}
接下来从剪贴板获取图片,wpf需要在项目添加引用System.Windows.Forms System.Drawing
if (System.Windows.Forms.Clipboard.ContainsImage())
{
System.Drawing.Image image = System.Windows.Forms.Clipboard.GetImage();
}
然后剪切。
System.Drawing.Image cutPicture(System.Drawing.Image image, Int32Rect window)
{
PrintScreen();
if (window.X + window.Width > image.Width)
window.Width = image.Width - window.X;
if (window.Y + window.Height > image.Height)
window.Height = image.Height - window.Y;
if (image == null)
{
//新建一个bmp图片
System.Drawing.Image bitmap = new System.Drawing.Bitmap(window.Width, window.Height);
//新建一个画板
System.Drawing.Graphics graphic = System.Drawing.Graphics.FromImage(bitmap);
//设置高质量查值法
graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//清空画布并以透明背景色填充
graphic.Clear(System.Drawing.Color.Transparent);
//在指定位置并且按指定大小绘制原图片的指定部分
graphic.DrawImage(image, new System.Drawing.Rectangle(0, 0, window.Width, window.Height), new System.Drawing.Rectangle(window.X, window.Y, window.Width, window.Height), System.Drawing.GraphicsUnit.Pixel);
return bitmap;
}
else
{
return null;
}
}
最后包装一下
System.Drawing.Image cutScreen(Int32Rect window)
{
PrintScreen();
Thread.Sleep(1000);
if (System.Windows.Forms.Clipboard.ContainsImage())
{
System.Drawing.Image image = cutPicture(System.Windows.Forms.Clipboard.GetImage(), Int32Rect window);
return image;
}
else
{
Console.WriteLine("clipboard doesn't contain picture");
return null;
}
}
System.Drawing.Image类有实例函数Save,保存很简单,就不细说了。
资料来源:
http://www.cnblogs.com/zhouyinhui/archive/2010/08/20/1804762.html
https://www.mgenware.com/blog/?p=285
http://blog.csdn.net/testcs_dn/article/details/39762017
c# wpf 利用截屏键实现截屏功能相关推荐
- 电子计算机开关及清屏键,计算机清屏键是什么
大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答. 计算机上ON/C键是开关及清屏键,CE键是清除键.开关及清屏键的功能即开关负责开关计算器,清屏是指将现有屏幕上的计算结果清零. 计 ...
- iphone怎么关闭浮屏键_iphone不常用功能有哪些 iphone可关闭功能开关汇总
入手了iphone很多人会觉得耗电,那么苹果手机如何省电?有什么方法可以省电?iphone不常用功能有哪些?下面是 iphone可关闭功能开关汇总,我们来尝试运用到自己的手机上. iphone不常用功 ...
- VB用API模拟截屏键PrintScreen
很多人用 SendKeys "{PRTSC}" 模拟截屏键 PrintScreen 的时候提示<错误:'70' 拒绝的权限>,于是经常遇到人问...干脆写下来 '声明 ...
- 鸿蒙系统有指关节截屏吗,拿了十年华为手机,只会使用组合键来截屏,网友:几千块白花了...
相信大家对于手机上的截屏功能都非常清楚吧!下面小编就要来好好讲讲华为手机里面的截屏操作方法,看看大家平时都用过哪几种? 一.高级截屏 1.三指下滑截屏 三指下滑截屏是华为手机第一种有趣的截屏操作方法, ...
- 苹果截屏快捷键_MacOS截屏的那些事儿
在使用Mac的时候,很多场景下我们都需要使用到截屏.不得不说,在MacOS中进行截屏是一件相当轻松的事情,因为MacOS原生的截屏功能就已经非常好用,完全不需要第三方软件.对比隔壁的Windows,那 ...
- 笔记本电脑截屏怎么截_电脑的截屏与录屏
电脑的截屏与录屏 相信大家都知道 QQ的截屏和录屏快捷键:截屏:Ctrl+Alt+A录屏:Ctrl+Alt+S 这种方便快捷的方式非常受人欢迎,但是万一我们的电脑上没有下载或打开QQ,我们该怎么办呢? ...
- android开发截屏代码,android截屏代码:C++实现
android截屏代码:C++实现 示例代码在: frameworks\base\services\surfaceflinger\tests\screencap\screencap.cpp /* * ...
- 苹果xr截屏怎么截_苹果系统截屏录屏+标记剪辑功能详解( iPhone/iPad/Mac)
苹果系统中的截屏和录屏.标记和剪辑功能一如它的其他产品设计,做得非常细致.在我们日常的工作中,不免会遇到这些功能,今天小编就给大家详细讲解下苹果系统截屏录屏.标记剪辑功能,希望对大家有所帮助! 001 ...
- 苹果6怎么截屏_iPhone怎么设置双击截屏 苹果手机双击截屏图文教程
对于经常需要截屏的iPhone用户来说,经常会羡慕安卓手机的各种截屏小技巧,如指关节截屏.手势截屏.隔空截屏等等,这些安卓手机内置的截屏功能,在iPhone上往往体验不上.尤其是iPhone X以上机 ...
- 三星android截屏快捷键是什么,三星截屏快捷键以及截屏方法
三星智能手机之所以会受到人们的疯狂购买,不仅仅是因为它拥有非常时尚的外观,同时还因为它拥有非常强的配置,可以大大满足人们对于游戏上网的需求.而现在有非常多的智能手机用户都会截屏,截屏几乎成为了人们日常 ...
最新文章
- linux没有mysql.server,[linux]centos7下解决yum install mysql-server没有可用包
- leetcode 986. Interval List Intersections | 986. 区间列表的交集(双指针)
- tableau三轴合并_举个栗子!Tableau技巧(34):同一张图表如何呈现多个度量
- kibana客户端工具操作ElasticSearch(增删改查三)
- 网页爬虫,HttpClient+Jericho HTML Parser 实现网页的抓取
- python tkinter库Entry控件Text控件
- python界面编程实例_python GUI库图形界面开发之PyQt5美化窗体与控件(异形窗体)实例...
- [转载] Python Pandas 的 all和any方法
- E-BERT: 电商领域语言模型优化实践
- 空间统计分析之距离-思维导图(1)
- mac使用jeb记录
- 信息系统服务器维护,信息系统运行维护服务方案(IT运维服务方案)-20210729025444.pdf-原创力文档...
- Nginx解决无法代理域名问题
- 2022年9月电子学会Python等级考试试卷(五级)答案解析
- 元宇宙:虚拟仿真技术的全面提升
- 团队作业8——Beta 阶段冲刺6th day
- html403禁止访问怎么解决,http403禁止访问错误产生的原因以及解决办法
- 卷积神经网络的一般步骤,卷积神经网络采用卷积
- lubuntu输入法设置_Ubuntu 18.04 16.04 设置输入法切换方法 中文输入法
- ubuntu14.04+windows双系统安装Ros indigo 与pioneer (测试的是3at和3dx) 键盘控制