最近做一个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 利用截屏键实现截屏功能相关推荐

  1. 电子计算机开关及清屏键,计算机清屏键是什么

    大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答. 计算机上ON/C键是开关及清屏键,CE键是清除键.开关及清屏键的功能即开关负责开关计算器,清屏是指将现有屏幕上的计算结果清零. 计 ...

  2. iphone怎么关闭浮屏键_iphone不常用功能有哪些 iphone可关闭功能开关汇总

    入手了iphone很多人会觉得耗电,那么苹果手机如何省电?有什么方法可以省电?iphone不常用功能有哪些?下面是 iphone可关闭功能开关汇总,我们来尝试运用到自己的手机上. iphone不常用功 ...

  3. VB用API模拟截屏键PrintScreen

    很多人用 SendKeys "{PRTSC}" 模拟截屏键 PrintScreen 的时候提示<错误:'70' 拒绝的权限>,于是经常遇到人问...干脆写下来 '声明 ...

  4. 鸿蒙系统有指关节截屏吗,拿了十年华为手机,只会使用组合键来截屏,网友:几千块白花了...

    相信大家对于手机上的截屏功能都非常清楚吧!下面小编就要来好好讲讲华为手机里面的截屏操作方法,看看大家平时都用过哪几种? 一.高级截屏 1.三指下滑截屏 三指下滑截屏是华为手机第一种有趣的截屏操作方法, ...

  5. 苹果截屏快捷键_MacOS截屏的那些事儿

    在使用Mac的时候,很多场景下我们都需要使用到截屏.不得不说,在MacOS中进行截屏是一件相当轻松的事情,因为MacOS原生的截屏功能就已经非常好用,完全不需要第三方软件.对比隔壁的Windows,那 ...

  6. 笔记本电脑截屏怎么截_电脑的截屏与录屏

    电脑的截屏与录屏 相信大家都知道 QQ的截屏和录屏快捷键:截屏:Ctrl+Alt+A录屏:Ctrl+Alt+S 这种方便快捷的方式非常受人欢迎,但是万一我们的电脑上没有下载或打开QQ,我们该怎么办呢? ...

  7. android开发截屏代码,android截屏代码:C++实现

    android截屏代码:C++实现 示例代码在: frameworks\base\services\surfaceflinger\tests\screencap\screencap.cpp /* * ...

  8. 苹果xr截屏怎么截_苹果系统截屏录屏+标记剪辑功能详解( iPhone/iPad/Mac)

    苹果系统中的截屏和录屏.标记和剪辑功能一如它的其他产品设计,做得非常细致.在我们日常的工作中,不免会遇到这些功能,今天小编就给大家详细讲解下苹果系统截屏录屏.标记剪辑功能,希望对大家有所帮助! 001 ...

  9. 苹果6怎么截屏_iPhone怎么设置双击截屏 苹果手机双击截屏图文教程

    对于经常需要截屏的iPhone用户来说,经常会羡慕安卓手机的各种截屏小技巧,如指关节截屏.手势截屏.隔空截屏等等,这些安卓手机内置的截屏功能,在iPhone上往往体验不上.尤其是iPhone X以上机 ...

  10. 三星android截屏快捷键是什么,三星截屏快捷键以及截屏方法

    三星智能手机之所以会受到人们的疯狂购买,不仅仅是因为它拥有非常时尚的外观,同时还因为它拥有非常强的配置,可以大大满足人们对于游戏上网的需求.而现在有非常多的智能手机用户都会截屏,截屏几乎成为了人们日常 ...

最新文章

  1. linux没有mysql.server,[linux]centos7下解决yum install mysql-server没有可用包
  2. leetcode 986. Interval List Intersections | 986. 区间列表的交集(双指针)
  3. tableau三轴合并_举个栗子!Tableau技巧(34):同一张图表如何呈现多个度量
  4. kibana客户端工具操作ElasticSearch(增删改查三)
  5. 网页爬虫,HttpClient+Jericho HTML Parser 实现网页的抓取
  6. python tkinter库Entry控件Text控件
  7. python界面编程实例_python GUI库图形界面开发之PyQt5美化窗体与控件(异形窗体)实例...
  8. [转载] Python Pandas 的 all和any方法
  9. E-BERT: 电商领域语言模型优化实践
  10. 空间统计分析之距离-思维导图(1)
  11. mac使用jeb记录
  12. 信息系统服务器维护,信息系统运行维护服务方案(IT运维服务方案)-20210729025444.pdf-原创力文档...
  13. Nginx解决无法代理域名问题
  14. 2022年9月电子学会Python等级考试试卷(五级)答案解析
  15. 元宇宙:虚拟仿真技术的全面提升
  16. 团队作业8——Beta 阶段冲刺6th day
  17. html403禁止访问怎么解决,http403禁止访问错误产生的原因以及解决办法
  18. 卷积神经网络的一般步骤,卷积神经网络采用卷积
  19. lubuntu输入法设置_Ubuntu 18.04 16.04 设置输入法切换方法 中文输入法
  20. ubuntu14.04+windows双系统安装Ros indigo 与pioneer (测试的是3at和3dx) 键盘控制

热门文章

  1. 为啥要看javac源代码
  2. 12月运营/营销/市场/广告人热点营销指南!
  3. 【java】临时文件
  4. 《人月神话》学习笔记
  5. 对一个list进行乱序处理
  6. Gmail:如何跟踪邮件阅读状态
  7. click与onclick的区别
  8. Bootstrap 新手学习手册---环境部署与网格系统
  9. 智能家居无创新,不智能
  10. 传说中的100句子记忆7000单词(51-100句)