17.2 图形绘制6

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

17.2.7 Screen类

Screen类从字面上看就知道是与屏幕显示相关的,表示单个系统上的一个或多个显示设备。

Screen常用属性:

  1. AllScreens:获取系统上所有屏幕的数组。
  2. BitsPerPixel:获取与数据的一个像素相关联的内存位数。
  3. Bounds:一个Rectangle值,屏幕高度和宽度的像素
  4. DeviceName:获取与屏幕关联的设备名称。
  5. Primary:指示某个屏幕是否为主显示屏
  6. PrimaryScreen:获取主屏幕。
  7. WorkingArea:一个Rectangle值,屏幕工作区的高度和宽度。这里所说的工作区是屏幕显示的桌面区域,不包括任务栏、停靠窗口和停靠工具栏。

【例 17.17【项目:code17-017】获取显示器信息。

        private void button1_Click(object sender, EventArgs e)

        {

            Screen[] scr = Screen.AllScreens;

            textBox1.Text = "显示器数量:" + scr.Length + "\r\n";

            for (int i = 0; i< scr.Length;  i++)

            {

                textBox1.Text += "显示器" + (i + 1) + "信息:" + "\r\n";

                textBox1.Text += (scr[i].Primary ? "主显示器":"非主显示器") + "\r\n";

                textBox1.Text += "显示设备:" + scr[i].DeviceName + "\r\n";

                textBox1.Text += "屏幕区域:" + scr[i].Bounds.X + "," + scr[i].Bounds.Y + "," + scr[i].Bounds.Width + "," + scr[i].Bounds.Height + "\r\n";

                textBox1.Text += "工作区域:" + scr[i].WorkingArea.X + "," + scr[i].WorkingArea.Y + "," + scr[i].WorkingArea.Width + "," + scr[i].WorkingArea.Height;

            }

        }

运行结果如下图所示:

图17-21 获取显示器信息

【例 17.18【项目:code17-018】屏幕截图。

屏幕截图先是通过Screen类的Bounds属性获得屏幕区域的Rectangle,从而获得屏幕的高度和宽度;然后可以通过Graphics对象的CopyFromScreen方法获得屏幕截图。

CopyFromScreen方法常用的一个重载版本:

public void CopyFromScreen( Point upperLeftSource, Point upperLeftDestination, Size blockRegionSize )

参数说明:

  1. upperLeftSource:位于显示器左上角的点。
  2. upperLeftDestination:位于目标图像左上角的点。
  3. blockRegionSize:要复制的显示器区域。

具体代码如下:

        private void button1_Click(object sender, EventArgs e)

        {

            string imgfile;

            SaveFileDialog sfd = new SaveFileDialog();

            sfd.Filter = "图片文件|*.jpg";

            if (sfd.ShowDialog() != DialogResult.OK)

                return;

            imgfile = sfd.FileName;

            //隐藏窗体

            this.Visible = false;

            //休息200毫秒,防止窗体还没有完全隐藏就截图

            System.Threading.Thread.Sleep(200);

            //获得主显示器

            Screen scr1 = Screen.PrimaryScreen;

            //获得窗体区域

            Rectangle rec = scr1.Bounds;

            Bitmap bmp =new Bitmap(rec.Width, rec.Height);

            Graphics g = Graphics.FromImage(bmp);

            //调用CopyFromScreen复制屏幕

            g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(rec.Width, rec.Height));

            g.Dispose();

            //保存图片

            bmp.Save(imgfile, System.Drawing.Imaging.ImageFormat.Jpeg);

            bmp.Dispose();

            //显示窗体

            this.Visible = true;

            label1.Text = "截屏保存到 " + imgfile;

        }

注意:通常家里的电脑只有一个显示器,所以只需要获得主显示器即可。

【例 17.19【项目:code17-019】屏幕取色。

        //标识是否开始取色

        bool isPick;

        //不可见的bitmap,保存了当前屏幕的截图

        Bitmap bmp;

        //当释放鼠标键时

        private void btnPick_MouseUp(object sender, MouseEventArgs e)

        {

            //停止取色

            isPick = false;

            //还原鼠标形状

            this.Cursor = Cursors.Default;

        }

        //按下鼠标时

        private void btnPick_MouseDown(object sender, MouseEventArgs e)

        {

            //如果按下鼠标左键

            if( e.Button == MouseButtons.Left)

            {

                //开始取色

                isPick = true;

                //获取了屏幕的截图,并保存在bmp里面

                Screen Scr = Screen.PrimaryScreen;

                Rectangle recSc = Scr.Bounds;

                bmp = new Bitmap(recSc.Width, recSc.Height);

                Graphics g = Graphics.FromImage(bmp);

                g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(recSc.Width, recSc.Height));

                //设置鼠标为十字形

                this.Cursor = Cursors.Cross;

            }

        }

        //当鼠标移动时开始取色

        private void btnPick_MouseMove(object sender, MouseEventArgs e)

        {

            int x, y;

            Point p = new Point(e.X, e.Y);

            Color colorPoint;

            //如果此时开始取色

            if( isPick )

            {

                //使用PointToScreen方法,将指定工作区点的位置计算成屏幕坐标

                x = btnPick.PointToScreen(p).X;

                y = btnPick.PointToScreen(p).Y;

                lblLocation.Text = "x:" + x + " y:" + y;

                //使用GetPixel方法在bmp对应坐标取色

                colorPoint = bmp.GetPixel(x, y);

                picPalette.BackColor = colorPoint;

                //获得颜色RGB分量

                lblRed.Text = colorPoint.R.ToString();

                lblGreen.Text = colorPoint.G.ToString();

                lblBlue.Text = colorPoint.B.ToString();

            }

        }

当鼠标左键在“取色”按钮上按下不放时,移动鼠标就可以在屏幕上取色了。

运行结果如下图所示:

图17-22 屏幕取色

17.2.8 坐标系变换

Graphics提供了几个特别的方法:

  1. TranslateTransform:平移坐标系统。常用的重载版本:

public void TranslateTransform( float dx, float dy )

参数说明:

  1. dx:平移的x坐标。
  2. dy:平移的y坐标。

将现有坐标系原点(或者理解为画布)平移到坐标(dx,dy)处。

  1. RotateTransform:旋转坐标系统。常用的重载版本:

public void RotateTransform ( float angle )

参数说明:

  1. angle:旋转的角度(以度为单位)。

将现有坐标系旋转相应角度,注意:这是顺时针旋转。

  1. ScaleTransform:缩放坐标系统。常用的重载版本:

public void ScaleTransform ( float sx, float sy )

参数说明:

  1. sx:x 方向的缩放比例。
  2. sy:y 方向的缩放比例。

将现有坐标系横坐标乘以sx,纵坐标乘以sy,如果sx或sy为负数,那么将坐标轴方向反向。注意:如果坐标轴反向,使用DrawString方法绘制文字,文字将会翻转。

  1. Save:保存当前坐标系统。
  2. Restore:还原保存的坐标系统。注意:Restore方法配合Save方法使用,使用后,Save保存的状态将会被移除,再次使用Restore将不会起作用。

【例 17.20【项目:code17-020】坐标系变换。

        Graphics g;

        LineCap endCap;

        GraphicsState gs;

        private void Form1_Load(object sender, EventArgs e)

        {

            g = this.CreateGraphics();

            endCap = LineCap.ArrowAnchor;

        }

            //绘制C#坐标系坐标轴

        private void button1_Click(object sender, EventArgs e)

        {

            //保存当前Graphics状态

            gs = g.Save();

            Pen mypen =new Pen(Color.Red, 4);

            LineCap endCap = LineCap.ArrowAnchor;

            mypen.EndCap = endCap;

            //绘制(0, 0)-(0, 150)的直线作为参考横坐标轴

            g.DrawLine(mypen, new Point(0, 0), new Point(0, 150));

            //绘制(0, 0)-(150,0)的直线作为参考纵坐标轴

            g.DrawLine(mypen, new Point(0, 0), new Point(150, 0));

        }

        //绘制直角坐标系坐标轴

        private void button2_Click(object sender, EventArgs e)

        {

            变换成常见的平面直角坐标系:

            //1、将坐标轴移动到1/2窗体宽度和1/2窗体高度处

            g.TranslateTransform(this.Width / 2, this.Height / 2);

            //2、缩放坐标轴,这里使用的是(1,-1)

            //表示横坐标轴不变,纵坐标轴反向

            g.ScaleTransform(1, -1);

            //定义宽度2的蓝色画笔

            Pen mypen =new Pen(Color.Blue, 2);

            mypen.EndCap = endCap;

            //绘制(0, 0)-(0, 150)的直线作为参考横坐标轴

            g.DrawLine(mypen, new Point(0, 0), new Point(0, 150));

            //绘制(0, 0)-(150,0)的直线作为参考纵坐标轴

            g.DrawLine(mypen, new Point(0, 0), new Point(150, 0));

        }

        //在平面直角坐标系下画矩形

        private void button3_Click(object sender, EventArgs e)

        {

            Pen mypen =new Pen(Color.Black, 2);

            g.DrawRectangle(mypen, new Rectangle(-50, -50, 100, 100));

        }

        //在C#坐标系下画矩形

        private void button4_Click(object sender, EventArgs e)

        {

            //还原Graphics状态

            g.Restore(gs);

            Pen mypen = new Pen(Color.Black, 2);

            g.DrawRectangle(mypen, new Rectangle(-50, -50, 100, 100));

        }

运行结果如下图所示:

图17-23 C#坐标系和平面直角坐标系对比

【例 17.21【项目:code17-021】绘制旋转的图形。

        private void button1_Click(object sender, EventArgs e)

        {

            Graphics g = this.CreateGraphics();

            //创建一个画笔

            Pen p = new Pen(Color.Blue, 1);

            //画个十字线坐标, 中间点为了看清, 用了一个4 * 4的矩形标出

            g.DrawLine(p, new Point(0, this.ClientRectangle.Height / 2), new Point(this.ClientRectangle.Width, this.ClientRectangle.Height / 2));

            g.DrawLine(p, new Point(this.ClientRectangle.Width / 2, 0), new Point(this.ClientRectangle.Width / 2, this.ClientRectangle.Height));

            g.DrawRectangle(new Pen(Color.Red, 2), new Rectangle(this.ClientRectangle.Width / 2, this.ClientRectangle.Height / 2, 2, 2));

            //将坐标轴原点平移到窗口中间

            g.TranslateTransform(this.ClientRectangle.Width / 2, this.ClientRectangle.Height / 2);

            //绘制10个正方形

            for(int i = 1;i<= 10;i++)

            {

                //以现在的坐标轴原点为中心绘制正方形

                g.DrawRectangle(new Pen(Color.Red, 2), new Rectangle(-50, -50, 100, 100));

                //旋转9度

                g.RotateTransform(9);

            }

        }

运行结果如下图所示:

图17-24 旋转的图形

 

学习更多vb.net知识,请参看vb.net 教程 目录

学习更多C#知识,请参看C#教程 目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/11017.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第一个Python程序

目录 1.命令行模式 2.Python交互模式 3.命令行模式和Python交互模式 4.SyntaxError 5.小结 2.使用文本编辑器 1.Visual Studio Code! 2.直接运行py文件 3.输入和输出 1.输出 2.输入 3.小结 在正式编写第一个Python程序前&#xff0c;我们先复习一下什么是命令行模式…

14-9-1C++STL的set容器

&#xff08;一&#xff09;set容器的基本概念 1. set是一个集合容器&#xff0c;其中所包含的元素是唯一的&#xff0c;集合中的元素按一定的顺序排列&#xff0c;元素插入过程是按排序规则插入&#xff0c;所以不能指定插入位置 2. set深用红黑树变体的数据结构实现&#xff…

数据分析系列--②RapidMiner导入数据和存储过程

一、下载数据 二、导入数据 1. 在本地计算机中创建3个文件夹 2. 从本地选择.csv或.xlsx 三、界面说明 四、存储过程 1.保存 Congratulations, you are done. 一、下载数据 点击下载AssociationAnalysisData.xlsx数据集 二、导入数据 1. 在本地计算机中创建3个文件夹 2. 从…

被裁与人生的意义--春节随想

还有两个月就要被迫离开工作了十多年的公司了&#xff0c;不过有幸安安稳稳的过了一个春节&#xff0c;很知足! 我是最后一批要离开的&#xff0c;一百多号同事都没“活到”蛇年。看着一批批仁人志士被“秋后斩首”&#xff0c;马上轮到我们十来个&#xff0c;个中滋味很难言清…

Docker自定义镜像

Dockerfile自定义镜像 一&#xff1a;镜像结构 镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。 我们以MySQL为例&#xff0c;来看看镜像的组成结构&#xff1a; 简单来说&#xff0c;镜像就是在系统函数库、运行环境基础上&#xff0c;添加应用程序文件、…

论文阅读(十六):利用线性链条件随机场模型检测阵列比较基因组杂交数据的拷贝数变异

1.论文链接&#xff1a;Detection of Copy Number Variations from Array Comparative Genomic Hybridization Data Using Linear-chain Conditional Random Field Models 摘要&#xff1a; 拷贝数变异&#xff08;CNV&#xff09;约占人类基因组的12%。除了CNVs在癌症发展中的…

ASP.NET Core 中间件

目录 一、常见的内置中间件 二、自定义中间件 三、中间件的执行顺序 四、其他自动逸中间件案例 1. 身份验证中间件 2、跨域中间件&#xff08;CORS&#xff09; ASP.NET Core 中&#xff0c;中间件&#xff08;Middleware&#xff09;是处理 HTTP 请求和响应的组件链。你…

JavaScript中的数组方法总结+详解

在JS中,数组方法是非常重要且常用的方法.在此整理总结一番. 1. javaScript常用数组方法 2.方法详解 1.push(); 功能: 在数组最后一位添加一个或多个元素,并返回新数组的长度,改变原数组.(添加多个元素用逗号隔开) var arr [1, 2, "c"];var rel arr.push(&q…

「全网最细 + 实战源码案例」设计模式——桥接模式

核心思想 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;将抽象部分与其实现部分分离&#xff0c;使它们可以独立变化。降低代码耦合度&#xff0c;避免类爆炸&#xff0c;提高代码的可扩展性。 结构 1. Implementation&#xff08;实现类…

动态规划DP 背包问题 完全背包问题(题目分析+C++完整代码)

概览检索 动态规划DP 概览&#xff08;点击链接跳转&#xff09; 动态规划DP 背包问题 概览&#xff08;点击链接跳转&#xff09; 完全背包问题 原题链接 AcWiing 3. 完全背包问题 题目描述 有 N种物品和一个容量是 V的背包&#xff0c;每种物品都有无限件可用。 第 i种物…

开源智慧园区管理系统对比五款主流产品探索智能运营新模式

内容概要 在这个数字化迅速发展的时代&#xff0c;园区管理也迎来了全新的机遇和挑战。众所周知&#xff0c;开源智慧园区管理系统作为一种创新解决方案&#xff0c;正逐步打破传统管理的局限性。它的开放性不仅使得系统可以根据具体需求进行灵活调整&#xff0c;也为用户提供…

Unity实现按键设置功能代码

一、前言 最近在学习unity2D&#xff0c;想做一个横版过关游戏&#xff0c;需要按键设置功能&#xff0c;让用户可以自定义方向键与攻击键等。 自己写了一个&#xff0c;总结如下。 二、界面效果图 这个是一个csv文件&#xff0c;准备第一列是中文按键说明&#xff0c;第二列…

稀疏混合专家架构语言模型(MoE)

注&#xff1a;本文为 “稀疏混合专家架构语言模型&#xff08;MoE&#xff09;” 相关文章合辑。 手把手教你&#xff0c;从零开始实现一个稀疏混合专家架构语言模型&#xff08;MoE&#xff09; 机器之心 2024年02月11日 12:21 河南 选自huggingface 机器之心编译 机器之心…

C++哈希(链地址法)(二)详解

文章目录 1.开放地址法1.1key不能取模的问题1.1.1将字符串转为整型1.1.2将日期类转为整型 2.哈希函数2.1乘法散列法&#xff08;了解&#xff09;2.2全域散列法&#xff08;了解&#xff09; 3.处理哈希冲突3.1线性探测&#xff08;挨着找&#xff09;3.2二次探测&#xff08;跳…

29.Word:公司本财年的年度报告【13】

目录 NO1.2.3.4 NO5.6.7​ NO8.9.10​ NO1.2.3.4 另存为F12&#xff1a;考生文件夹&#xff1a;Word.docx选中绿色标记的标题文本→样式对话框→单击右键→点击样式对话框→单击右键→修改→所有脚本→颜色/字体/名称→边框&#xff1a;0.5磅、黑色、单线条&#xff1a;点…

深入理解Java引用传递

先看一段代码&#xff1a; public static void add(String a) {a "new";System.out.println("add: " a); // 输出内容&#xff1a;add: new}public static void main(String[] args) {String a null;add(a);System.out.println("main: " a);…

Python从零构建macOS状态栏应用(仿ollama)并集成AI同款流式聊天 API 服务(含打包为独立应用)

在本教程中,我们将一步步构建一个 macOS 状态栏应用程序,并集成一个 Flask 服务器,提供流式响应的 API 服务。 如果你手中正好持有一台 MacBook Pro,又怀揣着搭建 AI 聊天服务的想法,却不知从何处迈出第一步,那么这篇文章绝对是你的及时雨。 最终,我们将实现以下功能: …

Qt之数据库操作三

主要介绍qt框架中对数据库的增加&#xff0c;删除和修改功能。 软件界面如下 程序结构 tdialogdata.h中代码 #ifndef TDIALOGDATA_H #define TDIALOGDATA_H#include <QDialog> #include<QSqlRecord> namespace Ui { class TDialogData; }class TDialogData : pub…

neo4j入门

文章目录 neo4j版本说明部署安装Mac部署docker部署 neo4j web工具使用数据结构图数据库VS关系数据库 neo4j neo4j官网Neo4j是用ava实现的开源NoSQL图数据库。Neo4作为图数据库中的代表产品&#xff0c;已经在众多的行业项目中进行了应用&#xff0c;如&#xff1a;网络管理&am…

JVM-运行时数据区

JVM的组成 运行时数据区-总览 Java虚拟机在运行Java程序过程中管理的内存区域&#xff0c;称之为运行时数据区。 《Java虚拟机规范》中规定了每一部分的作用 运行时数据区-应用场景 Java的内存分成哪几部分&#xff1f; Java内存中哪些部分会内存溢出&#xff1f; JDK7 和J…