C#做上位机软件——绘图并传输给下位机
拿到任务之后首先分成了几个部分:
1.绘图。学习了GDI+
2.图片保存。
3.将图片转换成byte[]。由于使用Socket通信,只能传输byte[]数据,所以这一步是向下位机传输的关键。
相应地,编程实现了下面几个功能:
1.使用GDI+画图并保存为bmp格式的图片。画图部分是书上的例子,只增加了保存的相应代码。
public partial class Form1 : Form
{
Bitmap bitmap;
Font myFont = new Font("Arial", , FontStyle.Bold);//定义字符串的样式
Rectangle ret = new Rectangle(, , , );//实例化
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
bitmap = new Bitmap(panel1.Width, panel1.Height);//用于保存
this.panel1.BackgroundImage = bitmap; int tem_Line = ;//圆的直径
int ci_L = ;//画笔
if (panel1.Width >= panel1.Height)
{
tem_Line = panel1.Height;
}
else
tem_Line = panel1.Width;
ret = new Rectangle(ci_L, ci_L, tem_Line - ci_L * , tem_Line - ci_L * );
Font Star_font = new Font("Arial", , FontStyle.Regular);
string star_str = "*"; Graphics g = Graphics.FromImage(bitmap);
//Graphics g = this.panel1.CreateGraphics();//实例化画图类
g.SmoothingMode = SmoothingMode.AntiAlias;//消除绘制的锯齿,作用比较明显
g.Clear(Color.White);//以白色清空panel1控件的背景
Pen myPen = new Pen(Color.Red, ci_L);//定义画笔
g.DrawEllipse(myPen, ret);//画椭圆(绘制圆) SizeF mySize = new SizeF(ret.Width, ret.Width);//实例化SizeF类 存储有序浮点数对,通常为矩形的宽度和高度。
mySize = g.MeasureString(star_str, Star_font);//对指定字符串进行测量(测量什么??????)
g.DrawString(star_str, Star_font, myPen.Brush, new PointF((ret.Width / 2F) + ci_L - mySize.Width / 2F,
ret.Height / 2F - mySize.Width / 2F));//在指定的位置绘制 mySize = g.MeasureString("专用", myFont);
g.DrawString("专用", myFont, myPen.Brush, new PointF((ret.Width / 2F) + ci_L - mySize.Width / 2F,
ret.Height / 2F + mySize.Width / 2F));//在指定的位置绘制
string tem = "testing";
int len = tem.Length;
float angle = + ( - len * ) / ; for (int i = ; i < len; i++)//将文字以指定的弧度进行绘制
{
g.TranslateTransform((tem_Line + ci_L / ) / , (tem_Line + ci_L / ) / );
g.RotateTransform(angle);//将指定的旋转用于Graphics类的变换矩阵??????????????
Brush myBrush = Brushes.Red;
g.DrawString(tem.Substring(i, ), myFont, myBrush, , );
g.ResetTransform();//将Graphics类的全局变换矩阵重置为单位矩阵?????????
angle += ;//设置下一个文字的角度
}
bitmap.Save(@"D:\myImage123.bmp", ImageFormat.Bmp);
}
}
2.将图片转换成byte[]
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Bitmap bitmap;
byte[] imageBytes;
MemoryStream ms;
private void button1_Click(object sender, EventArgs e)//打开图片
{
openFileDialog1.Filter = "*.bmp|*.bmp";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
if (bitmap != null)
bitmap.Dispose();
string fileName = openFileDialog1.FileName;
bitmap = new Bitmap(fileName);
/*if (bitmap.Width > bitmap.Height)//如果 图片 的宽度大于高度
{
pictureBox1.Width = panel1.Width;//设置控件的宽度
pictureBox1.Height = (int)((double)bitmap.Height * panel1.Width / bitmap.Width);
}
else
{
pictureBox1.Height = panel1.Width;
pictureBox1.Width = (int)((double)bitmap.Height * panel1.Width / bitmap.Width);
}*/
pictureBox1.Image = bitmap;//显示图片 }
} private void button2_Click(object sender, EventArgs e)
{
Image myImage = bitmap;//注意
ms = new MemoryStream();
imageBytes = new byte[ms.Length];//关于字节数组大小!!!!
myImage.Save(ms,ImageFormat.Gif);//存储到流
imageBytes=ms.ToArray();//将转换之后的结果赋值
richTextBox1.AppendText("长度:" + imageBytes.Length);
foreach (byte b in imageBytes)
{
richTextBox1.AppendText("转换之后的数据:" + b+"\r\n");
}
} private void button3_Click(object sender, EventArgs e)
{
MemoryStream ms = new MemoryStream(imageBytes);
Image returnImage = Image.FromStream(ms);
pictureBox2.Image= returnImage;//显示图片
}
}
至此,绘图、保存、转换都已经正确实现。
回归到最初的任务:画正弦函数曲线,并将数据传输给下位机(ARM),经下位机处理后将数据传回,并显示。要求上位机在画曲线时用户可以改变参数(这里设定的可变参数有幅度、周期、初相),参数改变就意味着有参照,而不是单一画出正弦函数图形,所以,必须添加坐标。最初研究添加坐标时,考虑的无非就是画坐标线,然后添加图形,但是这样的效果是无法将坐标与图形联系起来。为解决此问题,考虑了两种方案:固定坐标线,调整图像与坐标线建立联系;固定图形,让坐标去适应图形。这里需要说明的是,此时我考虑的这种所谓“坐标线”只是根据绘图区大小而画的直线,并非实际意义上的坐标系!当然这两种方案都没有实现,因为在研究过程中关注到了另外的组件:zedGraph。所以接下来的实现已经转移到这上面。
目前的效果:在zedGraph中绘制参数可变的正弦函数图像(含参考图像),然后保存为bmp格式的图片。这样加入之前将图片转换为byte[]的代码,然后将数据传输给下位机,就大功告成了!
兴奋时间还没有超过十秒钟,我就意识到自己从开始就绕了一个大圈:将数据传输给下位机并令下位机处理的,是指什么数据?仔细思考,有两种可能:
1、是列表中的坐标点,这样才能将处理之后的数据返回并再次显示,并非图片。
2、确实是图片,但即使是图片也不可能将转换之后的byte[]整个处理,因为这之间必然包含各种信息,如果不了解这些信息,如何告知下位机处理哪些数据,保留哪些数据?换句话说,也就是包含传输中数据格式的问题。
总之,无论如何,距离最后的结果还有距离。
Anyway 先将这段代码附上:
public partial class Form1 : Form
{
//private bool flag;
public Form1()
{
InitializeComponent();
} /*private void Form1_Paint(object sender, PaintEventArgs e)
{
if (flag)
{
CreateGraph(zedGraphControl1);
SetSize();
flag = false;
}
}
* */
private void button1_Click(object sender, EventArgs e)
{
//flag = true;
SetSize();
CreateGraph(zedGraphControl1);
} private void CreateGraph(ZedGraphControl zgc)
{
GraphPane myPane = zgc.GraphPane;
myPane.Clear();//消除上次痕迹
myPane.Title.Text = "正弦函数";
myPane.XAxis.Title.Text = "横坐标";
myPane.YAxis.Title.Text = "竖坐标"; //获取用户设定的数据
int T = Int32.Parse(numericUpDown1 .Text);//周期
int A = Int32.Parse(numericUpDown2.Text);//幅度
int B = Int32.Parse(numericUpDown3.Text);//初相
double w=*Math.PI/T;
double x, y1, y2;
PointPairList list1 = new PointPairList();//定义坐标数组
PointPairList list2 = new PointPairList();
for (int i = ; i < ; i++)//逐一描点画图
{
x = (double)i ;//从坐标原点开始
//y1 = 1.5 + Math.Sin((double)i * 0.2);
y1 = A*Math.Sin((double)i * w+B);
//y2 = 3.0 * (1.5 + Math.Sin((double)i * 0.2));
y2 =3.0*(Math.Sin((double)i * 0.1*Math.PI));//作为研究的参考图形
list1.Add(x, y1);
list2.Add(x, y2);
} // Generate a red curve with diamond
// symbols, and "Porsche" in the legend
LineItem myCurve = myPane.AddCurve("Sin()",
list1, Color.Red, SymbolType.Diamond); // Generate a blue curve with circle
// symbols, and "Piper" in the legend
LineItem myCurve2 = myPane.AddCurve("参考",
list2, Color.Blue, SymbolType.Circle); // Tell ZedGraph to refigure the
// axes since the data have changed
zgc.AxisChange(); //发送WM_PAINT消息放在应用程序的消息队列中,WM_PAINT消息的优先级很低,所以不会立即重绘
//zgc.Invalidate();//使窗口客户区无效,这样就需要重绘,
zgc.Refresh();//刷新显示 } private void Form1_Resize(object sender, EventArgs e)
{
//使控件大小随窗口大小改变而改变。是必要的
SetSize();
}
private void SetSize()
{
zedGraphControl1.Location = new Point(, );//20
zedGraphControl1.Size = new Size(ClientRectangle.Width-,ClientRectangle.Height-);//ClientRectangle.Width-22, ClientRectangle.Height-129);//20 20
//MessageBox.Show(ClientRectangle.Height.ToString() + "h w" + ClientRectangle.Width.ToString());
} private void button2_Click(object sender, EventArgs e)//保存图片
{
zedGraphControl1.Refresh();//刷新图片
pictureBox1.Image = zedGraphControl1.GetImage();//提取图片
pictureBox1.Image.Save(@"D:\myImage00.bmp", ImageFormat.Bmp);//保存图片
}
}
再接再励,继续。
C#做上位机软件——绘图并传输给下位机的更多相关文章
- "废物利用"也抄袭——“完全”DIY"绘图仪"<二、下位机程序设计>
就不说怎么组装了吧,一把辛酸泪.说程序,因为这有两把辛酸泪……一把给下位机的C代码一把为了VB.NET的图像处理……不过就上上一篇说的,它们可以正确运行了,并且今天克服了Arduino上电过程中步进电 ...
- [自娱自乐] 4、超声波测距模块DIY笔记(四)——终结篇·基于C#上位机软件开发
前言 上一节我们已经基本上把超声波硬件的发射和接收模块全部做好了,接下来我们着手开发一个软硬结合的基于C#的平面定位软件! 目录 一.整体思路 二.效果提前展示 2-1.软件部分展示 2-2.硬件部分 ...
- 【安富莱原创开源应用第1期】花式玩转网络摄像头之TCP上位机软件实现,高端大气上档次,速度2MB/S,华丽丽的界面效果
说明:1.例子是两年前做的,一直没有顾上整理出来,今天特地整理出来,开源出来给大家玩.2.上位机是emWin模拟器开发的,大家估计很难猜到,所以你会emWin话的,就可以轻松制作上位机.做些通信和控制 ...
- C++ MFC实现基于RFID读写器的上位机软件
C++ MFC实现基于RFID读写器的上位机软件 该博客涉及的完整工程托管在https://github.com/Wsine/UpperMonitor,觉得好请给个Star (/▽\=) 运行和测试环 ...
- 开源串口 Ymodem 上位机软件
概述 上位机使用Qt开发,计划整合多个工具为一体,用作以后的调试工具. 当前完成功能: 1.串口调试 支持hex和ascii 码发送,接受. 支持自动添加回车换行. 支持定时发送,最短间隔100ms, ...
- 我编写的EEPROM 上位机软件
进入模式: 上位机发送 消息 上位机EEPROM 按下进入模式 消息的ID号是:0x08111111 数据是: 00 01 ff 00 00 00 00 00 上位机显示 运行状态 :为进入模式 当我 ...
- 8-ESP8266 SDK开发基础入门篇--编写串口上位机软件
https://www.cnblogs.com/yangfengwu/p/11087558.html 咱用这个编写 ,版本都无所谓哈,只要自己有就可以,不同版本怎么打开 https://www.cnb ...
- 手机刷机软件与ROM的盈利模式分析
一. 智能手机的兴起不过短短几年时间,更新迭代已经让实体键盘成为回忆.智能手机带来的是人们生活习惯的改变,对于手机的重度依赖,是好是坏不去评价.智能手机相对于之前的手机最大的改变不仅仅是屏幕的飞速变大 ...
- C# WPF上位机实现和下位机TCP通讯
下位机使用北京大华程控电源DH1766-1,上位机使用WPF.实现了电压电流实时采集,曲线显示.上午在公司调试成功,手头没有程控电源,使用TCP服务端模拟.昨天写的TCP服务端正好排上用场. 界面如下 ...
随机推荐
- rt3070 驱动异常问题
新买的 Wi-Fi 网卡插在板子上,不能用.dmesg 查看,看到下面的内容. [ 9.501098] phy0 -> rt2x00lib_request_firmware: Error - F ...
- jQuery中json对象与json字符串互换
json字符串转json对象:jQuery.parseJSON(jsonStr); json对象转json字符串:JSON.stringify(jsonObj); 根据“|”把字符串变成数组.spli ...
- JavaScript系列文章:从let和const谈起
注册博客园账号也有好些年了,有事没事经常来逛逛,感觉博客园的同学们一直都很活跃,相比国内其他社区来讲,这里的技术氛围很浓,非常适合学习和交流,所以博主我也决定在这里驻扎了,在这里,博主希望能坚持写一些 ...
- php的empty(),trim(),strlen()方法
如果empty()函数的参数是非空或非零的值,则empty()返回FALSE.换句话说,"".0."0".NULL.array().var$var:以及没有任何 ...
- zabbix安装
在服务器10.128.17.136上安装 1.安装mysql \# yum -y install mysql mysql-server mysql-devel MySQL 配置文件/etc/my.cn ...
- java使double保留两位小数的多方法 java保留两位小数
这篇文章主要介绍了java使double类型保留两位小数的方法,大家参考使用吧 复制代码 代码如下: mport java.text.DecimalFormat; DecimalFormat d ...
- 制造高CPU使用率的简单方法
在群里有人问制造CPU占用率高的场景用来做测试.所谓做好事难,干“坏”事还不容易?这个需求有很多方法可以实现,比如使用一些压力测试工具.我首先想 到的是HASH JOIN.这个联接比较消耗CPU资源, ...
- 集中日志服务器Rsyslog
http://www.gaizaoren.org/archives/408 基于主机的管理一般需要收集服务器的日志信息用于及时发现错误,处理故障. 搭建linux下的集中日志服务器的程序一般可以用sy ...
- gulp工具rename
gulp 对文件批量重命名 gulp-rename重命名 var gulp = require('gulp'); var rename = require("gulp-rename" ...
- 购物车相关 js
<div class="caigou"> <form action="" method="post"> <di ...