http://blog.csdn.net/crystal_lz/article/details/9200859
上面是以前写的 不过现在重写了 增加了一些功能
源代码下载地址:http://download.csdn.net/detail/crystal_lz/9556929
第一次运行 会弹出此窗口进行快捷键的设置
因为需要修改注册表开机启动 所以需要使用管理员权限运行
启动截图的时候 [W,A,S,D] 微距移动鼠标
按下 V -> 自动框选的时候是否 只获取可见窗体
按下 T -> 是否获取透明窗体
按下 H -> 是否对webbrowser进行spy
在自动框选的时候 按下ctrl 的同时点击左键 弹出SpyTool
在自动框选的时候 按下 alt 的同时点击左键 将目标窗体设置为GIF截图窗体
这些快捷键都可以自己试一下
上面是对webbrowser进行spy的效果 是酷狗播放器
比起以前增加了 多显示器截图 其实要多显示器 很简单
/// <summary> /// 获取整个屏幕的矩形区域 /// </summary> /// <returns>矩形区域</returns> public static Rectangle GetDesktopRect() { Rectangle rect = new Rectangle(); rect.X = Win32.GetSystemMetrics(Win32.SM_XVIRTUALSCREEN); rect.Y = Win32.GetSystemMetrics(Win32.SM_YVIRTUALSCREEN); rect.Width = Win32.GetSystemMetrics(Win32.SM_CXVIRTUALSCREEN); rect.Height = Win32.GetSystemMetrics(Win32.SM_CYVIRTUALSCREEN); return rect; }
假设我现在是两个显示器 左边一个 右边一个分辨率都是 1920 * 1080 如果说 我右边的显示器是主显示器 那么 左边显示器的坐标是(-1920,0)开始的 所以在写代码的时候 窗体坐标到屏幕坐标的时候 需要注意
这次 程序增加了插件功能
插件可以自己编写 不过我想一般也没有去搞
namespace IPlugins { public interface IFilter { /// <summary> /// 获取插件显示的名字 /// </summary> /// <returns>插件名字</returns> string GetPluginName(); /// <summary> /// 获取插件在菜单上显示的图标 若不需要显示则返回null /// </summary> /// <returns>图标 否则 null</returns> Image GetPluginIcon(); /// <summary> /// 用于加载插件时候初始化调用 /// </summary> /// <param name="strStarPath">主程序启动路径</param> void InitPlugin(string strStarPath); ResultInfo ExecFilter(Image imgSrc); } }
一个Dll里面可以编写多个插件 不过到时候加载到右键菜单上面 会以dll名字作为分组 否则只有一个插件的话就没有子菜单
比如我上面演示的插件 工程是这样的
Gray中写了两个插件 那么到时候右键菜单中就会用Gray(Gray.dll)的名字作为分组 而如果dll中只有一个插件 那么就不用进行分组了
插件返回类型(悲剧的解决方案中忘了给这个类写注释了)
namespace IPlugins { public class ResultInfo : IDisposable { private Image _ResultImage; /// <summary> /// 获取插件处理后的图像 /// </summary> public Image ResultImage { get { return _ResultImage; } } private bool _IsModified; /// <summary> /// 告知程序图片是否被编辑 如果false 则忽略插件操作 如果true 则取出ResultImage作为结果 /// </summary> public bool IsModified { get { return _IsModified; } } private bool _IsClose; /// <summary> /// 如果true则截图窗体关闭 比如编写一个图片编辑器插件 /// 插件得到图片后想独占编辑 则可以在插件中Show一个窗体出来 然后返回一个ResultInfo /// 并将IsClose设置为true则 截图窗体就关闭了 剩下的操作就可以在自己编写的编辑器中进行 /// </summary> public bool IsClose { get { return _IsClose; } } public ResultInfo(Image imgResult, bool bModified, bool bClose) { this._ResultImage = imgResult; this._IsModified = bModified; this._IsClose = bClose; } public void Dispose() { if (this._ResultImage != null) this._ResultImage.Dispose(); } } }
//调用插件 private void item_Click(object sender, EventArgs e) { try { var result = ((sender as ToolStripMenuItem).Tag as IPlugins.IFilter).ExecFilter(m_imgLastLayer.Clone() as Bitmap); if (result.IsClose) this.Close();//如果插件需要关闭窗体(则插件里面可以自己show一个窗体出来 而不是ShowDialog) if (!result.IsModified) return;//如果图片没有被编辑 则忽略操作 m_imgCurrentLayer = result.ResultImage; imageCroppingBox1.Invalidate(imageCroppingBox1.SelectedRectangle); this.SetHistoryLayer(); imageCroppingBox1.IsLockSelected = true; } catch (Exception ex) { MessageBox.Show(ex.Message); } }
这是上面二值化插件弹出来的窗体 反正插件要怎么写 随便自己 可以不用弹出 比如上面的 黑白处理 和 反色处理 就不需要弹出窗体来进行一些参数设置
这个是上面插件的代码:
namespace Gray { public class PluginBinary : IFilter { public string GetPluginName() { return "二值化"; } public System.Drawing.Image GetPluginIcon() { return Properties.Resources.icon_binary; } public void InitPlugin(string strStarPath) { } public ResultInfo ExecFilter(System.Drawing.Image imgSrc) { Form1 frm = new Form1(imgSrc); if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK) { return new ResultInfo(frm.ResultImage, true, false); } return new ResultInfo(null, false, false); } } }
IPlugins.Dll里面有些自己写的控件 可以用 不过里面只写了我需要用到的控件 没几个
还有就是 由于平时经常用到打码 所以直接截图也内置了
选择 填充 和 马赛克 模式 反正就是自己尝试
如果不勾选马赛克 那么就是普通按照选择的颜色进行填充
不过这里注意 如果选择的是 绘制 和 马赛克 模式 你可能会感觉到绘制没有效果 这不是bug而是设定上就是这样的
只要勾选马赛克模式 无论画刷还是画笔都是以马赛克方式呈现的
如果画笔大小放大一点就能看到是什么效果了
GIF录制也经常用到 所以也内置了这个功能
GIF录制有两种模式 一种是窗体录制 一种是选择区域录制
选择区域录制就是上面截图看到的 选择一个区域右键菜单 -> 设置为GIF录制区域 这个很好理解
窗体录制是 只启动截图在自动框选的时候还没有确定区域的时候 按住ALT键然后点击鼠标左键 则会把自动框出来的窗体作为录制目标 和区域录制唯一的不同是
区域录制只会录制指定区域 而窗体录制则会跟踪窗体位置 比如窗体从屏幕左边移动到了右边依然会录制该窗体 而区域录制则办不到
GIF录制的时候 托盘图标右下角会变成绿色暂停录制是红色 否则显示正常图标
启动了录制gif切记 你正则录制 不然你忘了就悲剧了 就等着内存被沾满 然后蹦了吧
上面是录制的效果 可以选择高质量和低质量 可以点击复制 能直接将图片粘贴到QQ聊天窗体中去 为此我还分析了一下QQ的剪切板数据
{string[10]} [0]: "QQ_Unicode_RichEdit_Format" //MemoryStream 是一段xml [1]: "QQ_RichEdit_Format" //MemoryStream 同上(和上面的可以粘贴到聊天窗口) [2]: "DeviceIndependentBitmap" //直接使用Image类型即可(进行普通粘贴) [3]: "FileDrop" //string[] 文件路径(复制文件) [4]: "FileNameW" //string[] 同上 [5]: "FileName" //同上 [6]: "HTML Format" [7]: "System.String" [8]: "UnicodeText" [9]: "Text"这是我的代码
private void btn_copy_Click(object sender, EventArgs e) { if (!System.IO.Directory.Exists("./temp")) System.IO.Directory.CreateDirectory("./temp"); string strTempFile = "./temp/DevCap_"/*Developer Capture*/ + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".gif"; strTempFile = System.IO.Path.GetFullPath(strTempFile); pictureBox1.Image.Save(strTempFile); var i = new DataObject(); byte[] byData = Encoding.UTF8.GetBytes("<QQRichEditFormat><Info version=\"1001\"></Info><EditElement type=\"1\" filepath=\"" + strTempFile + "\" shortcut=\"\"></EditElement><EditElement type=\"0\"><![CDATA[]]></EditElement></QQRichEditFormat>"); i.SetData("QQ_Unicode_RichEdit_Format", new System.IO.MemoryStream(byData)); i.SetData("QQ_RichEdit_Format", new System.IO.MemoryStream(byData)); i.SetData("FileDrop", new string[] { strTempFile }); i.SetData("FileNameW", new string[] { strTempFile }); i.SetData("FileName", new string[] { strTempFile }); i.SetData("DeviceIndependentBitmap", pictureBox1.Image); Clipboard.SetDataObject(i, true); }
最后说明一下 虽然源代码开放 但是我实在是不希望看到那种 只改一个标题然后就重新发布说是自己写的那种情况 不是说不让用我的代码
只是说如果仅仅是使用或者在这个基础上修改代码 请保留代码一些原有的信息 比如我的ID:Crystal_lz (本想在每个类开头写个注释头的 估计写了也没用)
开放代码的目的是希望大家一起交流学习 顺便装个逼 而不是把东西送给你 对于我写的代码我完全可以选择开放或者不开放代码 但是既然我开放出来了 就希望别 “据为己有” 随便改改就说是你自己写的 即使你要这样做 请保留我的ID也好让我能继续装逼
原文:http://blog.csdn.net/crystal_lz/article/details/51737713