基于WINCE的图片浏览器开发
XX大学信息科学技术学院
《嵌入式系统》大作业
报告
项目名称:基于Wince的C#应用程序开发
——图片浏览器
姓名:学号:班级:
日期:2011-6-20
目 录
第一部分 概述 ......................................................................................................................... 2
1
1.1、Windows CE操作系统概述.................................................................................... 3
1.2、Windows CE应用程序介绍.................................................................................... 3
1.3、图片浏览器介绍 ...................................................................................................... 4
第二部分 设计任务 ................................................................................................................. 4
2.1、需求分析 .................................................................................................................. 4
2.2、程序功能 .................................................................................................................. 4
第三部分 设计原理 ................................................................................................................. 5
3.1、主要的类及控件介绍 .............................................................................................. 5
1.PictureBox控件 ..................................................................................................... 5
2.Image类 ................................................................................................................. 6
3.Bitmap类 ............................................................................................................... 6
4.Graphics类 ............................................................................................................ 6
3.2、功能设计 .................................................................................................................. 7
第四部分 #设计
# ................................................................................................................. 7
4.1、界面设计 .................................................................................................................. 8
4.2、代码设计 .................................................................................................................. 8
第五部分 系统测试与性能分析 ........................................................................................... 10
5.1、系统测试 ................................................................................................................ 10
第六部分 结论 ....................................................................................................................... 11
附录......................................................................................................................................... 11
1参考资料 ...................................................................................................................... 11
2设计步骤 ...................................................................................................................... 12
2.1操作系统的下载: ........................................................................................... 12
2.2应用程序部分: ............................................................................................... 18
3遇到的问题与解决方法 .............................................................................................. 20
4程序清单 ...................................................................................................................... 20
5课程体会 ...................................................................................................................... 33
第一部分 概述
嵌入式系统是“控制、监视或者辅助装置、机器和设备运行的装置”(devices used to control, monitor, or assist the operation of
equipment, machinery or plants)。从中可以看出嵌入式系统是软件和硬件的综合体,还可以涵盖机械等附属装置。目前国内一个普遍被认同的定义是:以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。
2
嵌入式操作系统种类繁多,例如:嵌入式Linux、Windows CE、VxWorks、pSOS 、等等,其中,Windows CE 操作系统是一款微软公司开发的嵌入式操作系统,它继承Windows操作系统的许多优点,而且资源充足,简单易学,在嵌入式得到大量应用。
随着手机、微型电脑设备等等嵌入式设备的蓬勃发展,嵌入式应用大量地发展了起来,许多在桌面广泛应用的程序越来越多地向嵌入式方向移植和应用,嵌入式应用程序正如火如荼地发展着~
Windows CE的开发工具与平台也有很多,例如Embedded Visual C++
等等,在本研究里面,我们选取Visual Studio 2005这个资源丰富,操作简便的开发平台,基于PAX270硬件平台进行图片浏览器的应用程序开发。 1.1、Windows CE操作系统概述
Windows CE是微软推出的一个32位、多线程、多任务的嵌入式操作系统,是微软专门为信息设备、移动应用、嵌入式应用等设计的嵌入式模块型操作系统。用户可选择、组合和配置Windows CE.NET的模块和组件来创建用户版的操作系统。
Windows CE采用层状的体系结构,具有层次性强、可移植性好、组件化可剪裁、强调编程接口和支持上层应用等特点。其从下而上可分为四层:硬件层,OEM硬件适配层,操作系统服务层,应用层。其层次结构如下图所示:
1.2、Windows CE应用程序介绍
由于Windows CE的特性,Windows CE开发出来的应用程序极为广泛,几乎覆盖了生活中的所有电气设备,如掌上PDA、手机、电视机顶盒、数字电视、车载电脑、数字相机、家庭自动化系统、安全系统、自动售货机、消费电子设备等等。
在Windows CE下,应用程序开发是针对给定的Windows CE,利用该平台提供的编程接口,使用特定的开发工具,实现特定功能的程序设计活动。由于Windows CE是一个可高度定制的操作系统,因此不同的基于Windows CE平台提供的API可能不同,在应用程序移植时,这一点必须引起应用开发人
3
员的高度重视。而且,Windows CE的API是桌面Windows系统的子集,因而它并不具备所有能在桌面环境下调用的API,这一点也是要注意的。 1.3、图片浏览器介绍
随着多媒体和互联网的快速发展,图片浏览功能成为了绝大部分计算机必不可少的基本功能之一。比如Windows操作系统自带的Windows图片浏览器、ACDSee看图软件等,都是为了方便用户查看、浏览及处理图片的优秀软件。同样,在相关嵌入式系统(如手机、MP4、数码相机等)中,图片浏览也成为了不可或缺的功能。为此,我们专门开发了一款基于Windows CE系统的图片浏览器,主要实现在Windows CE系统上对图片进行显示、浏览(上一张,下一张)、缩放、旋转以及简单的效果处理等。
第二部分 设计任务
随着多媒体和互联网的快速发展,图片浏览功能成为了绝大部分计算机必不可少的基本功能之一。比如windows操作系统自带的windows图片浏览器、ACDSee看图软件等,都是为了方便用户查看、浏览及处理图片的优秀软件。同样,在相关嵌入式系统(如手机、MP4、数码相机等)中,图片浏览也成为了不可或缺的功能。为此,我们专门开发了一款基于WINCE系统的图片浏览器,主要实现在WINCE系统上对图片进行显示、浏览(上一张,下一张)、缩放、旋转以及简单的效果处理等。
我们知道,图片浏览器作为一种常用的应用程序,其基本的功能都是差不多的,比如,显示一张图片,放大,缩小,旋转等等,因此我们实地亲自使用了在桌面环境下的一些图片应用程序,总结出一些比较基础的常用的功能,来作为我们的程序的需求。 2.1、需求分析
本软件为一个简单而且很实用的图片查看浏览器软件,不但可以进行图片的一些简单查看,浏览操作,删除、处理,而且还可以进行诸如雾化等效果转换等功能,是一款在嵌入式环境下比较适合广大计算机用户和非专业的用户的图片查看处理软件。考虑到部分非专业的普通大众用户的实际情况,所以软件必须不仅功能要齐全而且也不累赘,与此同时,界面的设计必须友好,按钮清楚醒目,操作风格要与桌面大众化程序保持一致。 2.2、程序功能
程序实现两大部分的功能:基本操作功能和效果处理功能。
基本操作功能:包括以下几个方面:“打开”、“上一张”、“下一张”、“删除”、“放大”、“缩小”、“左旋转”、“右旋转”、“关闭”。结构图如下面所示:
4
删除
上一张 打关 下一张 开 闭
图片文件(文件、文 结束 件夹)(图片的
可
显示出来 以是jpg、tif、bmp、
png、gif)
放大、缩小
左旋转
右旋转
效果处理功能:包括对图片进行“黑白”、“浮雕”、“锐化”、“雾化”处理,拓展了软件对图片的处理功能。结构图如下:
黑白
已打开 浮雕 显示效果 的图片
锐化
雾化
第三部分 设计原理
3.1、主要的类及控件介绍
使用C#语言开发基于WINCE系统的图片浏览器,主要需要使用到GDI+绘图功能以及部分WINDOWS控件,尤其是PictureBox控件。 1.PictureBox控件
要使开发出来的软件能够显示图片,PictureBox控件是必不可少的。PictureBox控件是一个图片显示控件,该控件可以显示的图片格式有BMP、GIF、JPEG和PNG等,而且还可以通过SizeMode属性设置图片的显示方式。其显示图片的基本用法如下:
PictureBox.Image=Image.FromFile(“图片路径”);
5
或
Bitmap bmp= new Bitmap(“图片路径”);
PictureBox.Image=bmp;
2.Image类
由PictureBox的用法可以看出,PictureBox需要同Image类配合使用。Image类是一个抽象类,该类提供了基本的图片访问功能。由于Image类是一个抽象类,所以不能直接使用其本身实例化一个对象,但是,我们可以使用FromFile和FromStream等静态方法,或Image类的子类(如Bitmap类)构造其实例。创建Image类的方法如下所示:
Image image=Image.FromFile(“图片路径”);
或
System.IO.Stream stream=new System.IO.FileStream(“图片
路径”, System.IO.FileMode.Open);
Image image=Image.FromStream(stream);
Stream.Close();
或
Image image=new Bitmap(“图片路径”);
经多次实验
明,在WINCE6.0系统中只支持第三种,即通过Bitmap类来构造Image类的实例。
3.Bitmap类
位图(bitmap)是由许多像小方块一样的像素组成的图形。Bitmap类封装了位图及其属性的像素数据,其主要的方法有GetPixel,SetPixel,LockBits,UnlockBits等。其在WINCE中常用的实例化方法有如下几种:
Bitmap bmp=new Bitmap(“图片路径”);//从指定的文件初始化
//其实例;
或
Bitmap bmp=new Bitmap(Image image);//从指定的现有图片初始
化//其实例;
或
Bitmap bmp=new Bitmap(int width,int height);
4.Graphics类
在实现缩放及旋转等图片处理功能时,经常要使用到Graphics类。Graphics类是System.Drawing命名空间下最主要的类,绘制所有图形都需要调动该类的方法来实现,例如可以使用DrawLine方法画一条直线,使用DrawImage方法画一副图像等。Graphics类没有构造函数,所有不能使用new关键字生成一个Graphics类的实例,通常可以用如下三种方式创建Graphics对象:
6
Graphics g=Control.CreateGraphics();//使用控件的
//CreateGraphics方法创建实例; 或
Graphics g=e.Graphics;// 使用控件的Paint事件或重载OnPaint方
//法,从PaintEventArgs对象中的Graphics
//属性获取Graphics对象。
或
图片路径”); Image image=Image.FromFile(“
Graphics g=Graphics.FromImage(image);
在WINCE系统上,我们采用了第三种方法,即通过使用Graphics类的静态方法,从一些对象的句柄中获取Graphics对象。通过使用获得的Graphics对象的DrawImage方法,实现我们开发软件的缩放及选择功能。
3.2、功能设计
我们设计的图片浏览器在功能上主要可以分为两大功能模块:基本操作功能模块和效果处理功能模块。系统功能图如下:
上一张、下一张 基本图 操作缩小、放大 片 功能浏打开、关闭、删除 模块 览 左旋转、右旋转 器
效果 处理 黑雾锐浮功能白 化 化 雕 模块
第四部分 设计方案
我们通过对一些桌面图片处理浏览程序进行研究,总结了它们的一些基本特征,从而构想出我们的设计方案。
开发环境:Windows XP
开发工具:Microsoft Visual studio2005
硬件环境: 台式计算机、嵌入式处理器:PAX270
运行环境:Windows XP、Visual Studio 2005、WindowsCE5.0(不包含图片浏览组件)、亿道嵌入式开发板EELiod270教学开发平台。
7
4.1、界面设计
在界面设计中,我们参考了大众化软件常见界面,以图片显示区域为中心,上面设置菜单栏,菜单栏下拉有选项供操作,下面设置快速操作按钮,方便用户快速使用对图片进行操作的功能。整体效果如下所示:
4.2、代码设计
整个代码分控件和纯代码这两部分。
控件部分:包括PictureBox(用来显示图片)、mainMenu(用来设置菜单栏)、openFileDialog(打开文件对话框)、saveFileDialog(保存文件对话框),还有其他7个按钮(“打开”、“上一张”等等)。
纯代码部分:头文件部分,引用系统头文件,如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
8
using System.IO;
using System.Drawing.Imaging;
对于在菜单和快捷按钮存在一致的操作,例如菜单栏中的“上一张”和快捷
按钮的“上一张”,我们将函数独立出来,在菜单栏“上一张”操作或快捷按钮
“上一张”有事件触发时,只用一个语句就可以调用这函数,这样就减少了代码
的数量,变得精简;对于“雾化”这里效果操作功能,我们设置其在菜单栏被触
发时直接编写对应的事件。例子如下:
private void previous()//实现“上一张”功能的函数
{
try
{
if (index == 0)
{
MessageBox.Show("这已经是第一张了.", "温馨提醒~");
}
else
{
this.pictureBox1.Image.Dispose();
curFile = fileInDir[--index].ToString();
curBmp = new Bitmap(curFile);
this.pictureBox1.Image = curBmp;
displayImage();
}
}
catch (NullReferenceException)
{
MessageBox.Show("请先打开一张图片~", "温馨提醒~");
}
}
private void menuItem7_Click(object sender, EventArgs e)//菜单栏的“上
一张”调用“上一张”功能函数
{ previous(); }
private void menuItem21_Click(object sender, EventArgs e)//菜单栏“雾
化”功能实现
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap bitmap = new Bitmap(Width, Height);
Bitmap MyBitmap = (Bitmap)this.pictureBox1.Image;
9
Color pixel;
for (int x = 1; x < Width - 1; x++)
for (int y = 1; y < Height - 1; y++)
{
System.Random MyRandom = new Random();
int k = MyRandom.Next(123456);
//像素块大小
int dx = x + k % 19;
int dy = y + k % 19;
if (dx >= Width)
dx = Width - 1;
if (dy >= Height)
dy = Height - 1;
pixel = MyBitmap.GetPixel(dx, dy);
bitmap.SetPixel(x, y, pixel);
}
this.pictureBox1.Image = bitmap;
}
第五部分 系统测试与性能分析
作为一款大众化软件,其稳定性要求也是很高的,所以对软件系统进行测试
和性能的分析是很重要的,所以我们也简单地进行一些相关的测试。
5.1、系统测试
系统测试包括功能测试和用户界面测试。
1. 功能测试,包括打开功能、图片操作功能、效果操作功能。
打开功能测试结果如下所示:
预想能打开的图片的格能否打开, 显示效果
式
jpeg 能 完美
gif 能 一般,没动态效果
bmp 不能 没效果
png 能 完美
图片操作功能测试结果如下:
按钮名称 结果 按钮名称 结果
上一张 正常 缩小 正常
下一张 正常 右旋转 正常
删除 正常 左旋转 正常
放大 正常 关闭 正常
效果操作功能测试结果如下:
10
效果名称 结果
黑白 正常
雾化 正常
锐化 正常
2. 用户界面测试:经过组员测试,得到如下结果:PictureBox控件位置合适,显示图片时大小适中,不会产生变形;菜单栏布局良好,快捷按钮方便用户操作;唯独软件没有比较“炫”的效果,这是我们以后要努力的方向。 第六部分 结论
Windows CE是微软公司嵌入式、移动计算平台的基础,它是一个开放的、可升级的32位嵌入式操作系统,是基于掌上型电脑类的电子设备操作系统。与Windows 95/98、Windows NT不同的是,Windows CE是所有源代码全部由微软自行开发的嵌入式新型操作系统,其操作界面虽来源于Windows 95/98,但Windows CE是基于WIN32 API重新开发、新型的信息设备的平台。Windows CE具有模块化、结构化和基于Win32应用程序接口和与处理器无关等特点。Windows CE不仅继承了传统的Windows图形界面,并且在Windows CE平台上可以使用Windows 95/98上的编程工具(如Visual Basic、Visual C++等)、使用同样的函数、使用同样的界面风格,使绝大多数的应用软件只需简单的修改和移植就可以在Windows CE平台上继续使用。
总的来说,在可见的未来,以Windows CE的嵌入式系统,一定会在后PC时代发挥出巨大的作用和衍生丰富的应用。
附录
1参考资料
[1] 黄国平 等编著。《C#实用开发大全》。电子工业出版社,2008.1 [2] 吕伟臣,霍言,吕宝臣。《Visual C# 2005入门与提高》。清华大学出版社,2006.9 [3] 马文华。《嵌入式系统设计与开发》。科学出版社, 2006.3
[4] 宁杨、陆贵强。《Windows CE.net内核定制及应用开发》,电子工业出版社,2005.2 [5] 何宗键.《Windows CE嵌入式系统》,北京航空航天出版社,2006.9 [6] 相关网页:www.codeproject.com , www.csdn.net 以及百度文库等。
11
2设计步骤
2.1操作系统的下载:
第一步: 从“开始->所有程序->附件->通讯->超级终端”新建一个超级中断链接。
【图1】超级终端连接描述
第二步: 选择连接串口,并将串口波特率设为:38400,数据流控制选择“无”,按“确定”
按钮
【图2】超级终端设置选项
12
【图3】超级终端成功设置菜单
第三步: 确定一下PC与目标平台的串口接口线已接上,然后打开平台电源开关,Bootloader
程序时,按空格键进入Eboot的菜单选项中。
【图4】超级终端显示Boot Loader 启动菜单选项
13
第四步: 启动Visual Studio 2005,在Target->connectivity Option中打开映象的下载配置选项。
【图5】Connectivity Options 菜单选项
第五步: 在Download与Transport 选项都选择“Ethernet”.在Debugger中选择“None”.
【图6】Target Device Connectivity Options 选项
14
第六步: 点击Download选择右边的“Settings”,让PB来检测设备名。用网线连通PC和目
标平台,将PC和目标平台的网络连接设置在同一网段,根据超级终端的Eboot菜单提
示,选取“D”项,即按键盘上的D键。
【图7】Ethernet download Settings 设置选项
【图8】目标平台发送广播包选项
15
第七步: 在Ethernet Download Settings中,就可以自动检测到目标设备名,点击“Active
Devices”中的设备名就可以把设备名添加到“Device Boot Name”中去。然后点击“OK”,
再点“Apply”按钮,然后按“Close”按钮关闭“Target Device connectivity Options”窗
口.
【图9】检测连接选项
第八步: 从Visual Studio2005的Target->Attach Device菜单中,选中NK.BIN文件,连接目
标平台。
16
【图10】Attach device 菜单选项
第九步: 在弹出的下载窗口就可以看到NK下载的进度。
【图11】NK下载过程
第十步: 操作系统映像下载完毕后,Windows Embedded CE 6.0操作系统自动启动。
【图45】Windows CE 6.0 启动界面
17
2.2应用程序部分:
1.打开VisualStudio2005,选择File->New->Project,新建基于WINCE5.0的C#设备应用程序。如下图所示:
2.设计界面,添加菜单项和相关功能控件,如图所示:
3.分别双击“打开”,“下一张”,“上一张”,“删除”,“放大”,“缩小”,
18
“右旋转”,“左选择”,“关闭”,以及菜单栏的菜单项。VisualStudio2005将自动生成消息函数架构。并在函数体中添加相应代码(请查阅“代码清单”部分),如下图所示:
4.程序设计完成之后,点击Build-〉Build Solution。纠正提示的错误及警告之后,点击Debug-〉Start Debugging 。在出现的设备部署,选择WinCE6EEliod ARMV4I Device,如下图所示。程序在实验箱可以正常运行:
19
3遇到的问题与解决方法
问题一:设计界面时,根据我们对其他图片浏览器产品的观察,我们本来打算采用菜单栏和工具条来构成主要的界面。但在WINCE系统中,工具条的按钮项只能用图片集ImageList中的图像来表示,不支持文字Text。这样如果图片太小,用户可能就看不清各个按钮项的功能。
解决方法:为了方便使用,我们决定舍弃工具条而采用放在面板Panel中排成一列的按钮Button控件来起到相同的效果。
问题二:在代码实现时,我们发现在自己电脑上可以成功运行的代码在实验室的实验箱上往往会报错。原因是一些可以在windows 环境下使用的函数在WINCE系统上不支持,或者是构造对象时需要使用到的类的参数不同。比如,在创建缩放图像时,本来Graphics类有ScaleTransform()函数来实现比例缩放,但在WINCE系统不支持;再比如,旋转图片本来可以直接使用RotateTransform()函数来实现,但在WINCE系统也是无法使用。 解决方法:在缩放时,经过多次尝试,最终发现了Graphics的DrawImage()函数可以间接实现该功能;为了实现旋转功能,我们只好逐像素的给以旋转,在大大降低效率的基础上才实现了这个功能。其他显示效果处理功能也主要使用了类似的方法。 4程序清单
全部代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Drawing.Imaging;
namespace PictureBrowser1
{
public partial class Form1 : Form
{
private String dirPath; //文件所在文件夹路径
private ArrayList fileInDir; //用ArrayList存储文件夹中的图片文件
private int index; //图片文件索引,用于实现上一张、下一张浏览
private String curFile; //当前图片文件的路径
private Bitmap curBmp; //当前图片文件的位图
public Form1()
{
20
InitializeComponent();
panel2.AutoScroll = true;
}
private void open() //文件打开函数
{
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
if (this.pictureBox1.Image != null)
{
this.pictureBox1.Image.Dispose();
this.pictureBox1.Image = null;
}
String filename = this.openFileDialog1.FileName;
try
{
curFile = filename;
curBmp = new Bitmap(curFile);
this.pictureBox1.Image = curBmp;
displayImage();
dirPath = filename.Substring(0, filename.LastIndexOf("\\"));
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(dirPath);
System.IO.FileInfo[] fileInfo = dirInfo.GetFiles();
fileInDir = new ArrayList();
if (fileInDir.Count > 0)
fileInDir.Clear();
foreach (FileInfo fi in fileInfo)
{
if (fi.Extension == ".JPG" || fi.Extension == ".jpg" || fi.Extension ==
".jpeg" || fi.Extension == ".tif" || fi.Extension == ".png" || fi.Extension == ".bmp" || fi.Extension == ".BMP" ||
fi.Extension == ".gif" || fi.Extension == ".GIF")
{
fileInDir.Add(fi.FullName.ToString());
}
}
for (index = 0; index < fileInDir.Count; index++)
{
if (fileInDir[index].ToString() == filename)
{
break;
}
}
}
21
catch (Exception excep)
{
Console.WriteLine(excep);
MessageBox.Show("请选择后缀名为“JPG/PNG/JPEG/GIF/TIF/BMP”的图片~", "温馨提醒~");
}
}
else
{
MessageBox.Show("请先选择一张图片~", "温馨提醒~");
}
}
private void close() //文件关闭函数
{
if (this.pictureBox1.Image != null)
{
this.pictureBox1.Image.Dispose();
this.pictureBox1.Image = null;
curFile = "";
curBmp = null;
}
}
private void next() //浏览下一张函数
{
try
{
if (index == fileInDir.Count - 1)
{
MessageBox.Show("这已经是最后一张了.", "温馨提醒~");
}
else
{
this.pictureBox1.Image.Dispose();
curFile = fileInDir[++index].ToString();
curBmp = new Bitmap(curFile);
this.pictureBox1.Image = curBmp;
displayImage();
}
}
catch (NullReferenceException)
{
MessageBox.Show("请先打开一张图片~", "温馨提醒~");
}
22
}
private void previous() //浏览上一张函数
{
try
{
if (index == 0)
{
MessageBox.Show("这已经是第一张了.", "温馨提醒~");
}
else
{
this.pictureBox1.Image.Dispose();
curFile = fileInDir[--index].ToString();
curBmp = new Bitmap(curFile);
this.pictureBox1.Image = curBmp;
displayImage();
}
}
catch (NullReferenceException)
{
MessageBox.Show("请先打开一张图片~", "温馨提醒~");
}
}
private void max() //图片放大函数
{
try
{ int w = (int)(this.pictureBox1.Image.Width * 1.1);
int h = (int)(this.pictureBox1.Image.Height * 1.1);
Bitmap bmpo = curBmp;
Bitmap bmpn = new Bitmap(w, h);
Graphics g = Graphics.FromImage(bmpn);
g.DrawImage(bmpo, new Rectangle(0, 0, w, h), new Rectangle(0, 0, bmpo.Width,
bmpo.Height), GraphicsUnit.Pixel);
g.Dispose();
curBmp = bmpn;
this.pictureBox1.Image.Dispose();
this.pictureBox1.Image = curBmp;
displayImage();
}
catch (NullReferenceException)
{
23
MessageBox.Show("请先打开一张图片~", "温馨提醒~");
}
}
private void min() //图片缩小函数
{
try
{
int w = (int)(this.pictureBox1.Image.Width * 0.9);
int h = (int)(this.pictureBox1.Image.Height * 0.9);
Bitmap bmpo = curBmp;
Bitmap bmpn = new Bitmap(w, h);
Graphics g = Graphics.FromImage(bmpn);
g.DrawImage(bmpo, new Rectangle(0, 0, w, h), new Rectangle(0, 0, bmpo.Width, bmpo.Height), GraphicsUnit.Pixel);
g.Dispose();
curBmp = bmpn;
this.pictureBox1.Image.Dispose();
this.pictureBox1.Image = curBmp;
displayImage();
}
catch (NullReferenceException)
{
MessageBox.Show("请先打开一张图片~", "温馨提醒~");
}
}
private void left() //左旋转函数
{
try
{
Bitmap originalBitmap = curBmp;
int rotationAngle = 270;
int newWidth = originalBitmap.Height;
int newHeight = originalBitmap.Width;
Bitmap rotatedBitmap = new Bitmap(newWidth, newHeight); #if ALLOW_UNSAFE_CODE
InternalRotateImage(rotationAngle, originalBitmap, rotatedBitmap);
#else
InternalRotateImage(rotationAngle, originalBitmap, rotatedBitmap);
#endif
this.pictureBox1.Image = rotatedBitmap;
curBmp = rotatedBitmap;
displayImage();
24
}
catch (NullReferenceException)
{
MessageBox.Show("请先打开一张图片~", "温馨提醒~");
}
}
private void right() //右旋转函数
{
try
{
Bitmap originalBitmap = curBmp;
int rotationAngle = 90;
int newWidth = originalBitmap.Height;
int newHeight = originalBitmap.Width;
Bitmap rotatedBitmap = new Bitmap(newWidth, newHeight); #if ALLOW_UNSAFE_CODE
InternalRotateImage(rotationAngle, originalBitmap, rotatedBitmap);
#else
InternalRotateImage(rotationAngle, originalBitmap, rotatedBitmap);
#endif
this.pictureBox1.Image = rotatedBitmap;
curBmp = rotatedBitmap;
displayImage();
}
catch (NullReferenceException)
{
MessageBox.Show("请先打开一张图片~", "温馨提醒~");
}
}
#if ALLOW_UNSAFE_CODE
private static void InternalRotateImage(int rotationAngle, Bitmap originalBitmap,
Bitmap rotatedBitmap)
{
int newWidth = rotatedBitmap.Width;
int newHeight = rotatedBitmap.Height;
int originalWidth = originalBitmap.Width;
int originalHeight = originalBitmap.Height;
int newWidthMinusOne = newWidth - 1;
int newHeightMinusOne = newHeight - 1;
BitmapData originalData = originalBitmap.LockBits(new Rectangle(0, 0, originalWidth,
originalHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
BitmapData rotatedData = rotatedBitmap.LockBits(new Rectangle(0, 0,
rotatedBitmap.Width, rotatedBitmap.Height), ImageLockMode.WriteOnly,
25
PixelFormat.Format32bppRgb);
unsafe
{
int* originalPointer = (int*)originalData.Scan0.ToPointer();
int* rotatedPointer = (int*)rotatedData.Scan0.ToPointer();
switch (rotationAngle)
{
case 90:
for (int y = 0; y < originalHeight; ++y)
{
int destinationX = newWidthMinusOne - y;
for (int x = 0; x < originalWidth; ++x)
{
int sourcePosition = (x + y * originalWidth);
int destinationY = x;
int destinationPosition = (destinationX + destinationY *
newWidth);
rotatedPointer[destinationPosition] = originalPointer[sourcePosition];
}
}
break;
case 270:
for (int y = 0; y < originalHeight; ++y)
{
int destinationX = y;
for (int x = 0; x < originalWidth; ++x)
{
int sourcePosition = (x + y * originalWidth);
int destinationY = newHeightMinusOne - x;
int destinationPosition = (destinationX + destinationY *
newWidth);
rotatedPointer[destinationPosition] = originalPointer[sourcePosition];
}
}
break;
}
originalBitmap.UnlockBits(originalData);
rotatedBitmap.UnlockBits(rotatedData);
}
}
#else
26
private static void InternalRotateImage(int rotationAngle, Bitmap originalBitmap, Bitmap rotatedBitmap) //图片选择实现函数
{
int rotatedWidthMinusOne = rotatedBitmap.Width - 1;
int rotatedHeightMinusOne = rotatedBitmap.Height - 1;
int originalWidth = originalBitmap.Width;
int originalHeight = originalBitmap.Height;
switch (rotationAngle)
{
case 90:
for (int y = 0; y < originalHeight; ++y)
{
for (int x = 0; x < originalWidth; ++x)
rotatedBitmap.SetPixel(rotatedWidthMinusOne - y, x,
originalBitmap.GetPixel(x, y));
}
break;
case 270:
for (int y = 0; y < originalHeight; ++y)
{
for (int x = 0; x < originalWidth; ++x)
rotatedBitmap.SetPixel(y, rotatedHeightMinusOne - x,
originalBitmap.GetPixel(x, y));
}
break;
}
}
#endif
private void delete() //图片删除函数
{
DialogResult dlgResult = MessageBox.Show("您确定要删除此图片,", "信息提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
if (dlgResult == DialogResult.OK)
{
File.Delete(fileInDir[index].ToString());
fileInDir[index] = fileInDir[++index];
curFile = fileInDir[index].ToString();
curBmp = new Bitmap(curFile);
this.pictureBox1.Image = curBmp;
27
}
}
private void displayImage() //图片显示自定义函数
{
this.pictureBox1.Height = curBmp.Height;
this.pictureBox1.Width = curBmp.Width;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
if (pictureBox1.Width < panel2.Width)
pictureBox1.Left = (panel2.Width - pictureBox1.Width) / 2;
else
pictureBox1.Left = 0;
if (pictureBox1.Height < panel2.Height)
pictureBox1.Top = (panel2.Height - pictureBox1.Height) / 2;
else
pictureBox1.Top = 0;
}
//以下主要是按钮事件,触发相应的函数。
private void menuItem2_Click(object sender, EventArgs e)
{
open();
}
private void menuItem3_Click(object sender, EventArgs e)
{
close();
}
private void menuItem4_Click(object sender, EventArgs e)
{
DialogResult result = MessageBox.Show("确定要退出系统吗,", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
if (result == DialogResult.OK)
{
if (this.pictureBox1.Image != null)
{
this.pictureBox1.Image.Dispose();
this.pictureBox1.Image = null;
}
Application.Exit();
}
}
private void button1_Click(object sender, EventArgs e)
{
open();
}
private void menuItem7_Click(object sender, EventArgs e)
28
{
previous();
}
private void menuItem8_Click(object sender, EventArgs e)
{
next();
}
private void menuItem9_Click(object sender, EventArgs e)
{
right();
}
private void menuItem10_Click(object sender, EventArgs e)
{
left();
}
private void menuItem11_Click(object sender, EventArgs e)
{
max();
}
private void menuItem12_Click(object sender, EventArgs e)
{
min();
}
private void menuItem13_Click(object sender, EventArgs e)
{
delete();
}
//以下主要是图片效果处理函数
private void menuItem18_Click(object sender, EventArgs e) //黑白效果
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap bitmap = new Bitmap(Width, Height);
Bitmap MyBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel;
for (int x = 0; x < Width; x++)
for (int y = 0; y < Height; y++)
{
pixel = MyBitmap.GetPixel(x, y);
int r, g, b, Result = 0;
r = pixel.R;
g = pixel.G;
b = pixel.B;
//实例程序以加权平均值法产生黑白图像
29
int iType = 2;
switch (iType)
{
case 0://平均值法
Result = ((r + g + b) / 3);
break;
case 1://最大值法
Result = r > g ? r : g;
Result = Result > b ? Result : b;
break;
case 2://加权平均值法
Result = ((int)(0.7 * r) + (int)(0.2 * g) + (int)(0.1 * b));
break;
}
bitmap.SetPixel(x, y, Color.FromArgb(Result, Result, Result));
}
this.pictureBox1.Image = bitmap;
}
private void menuItem19_Click(object sender, EventArgs e) //浮雕效果
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap bitmap = new Bitmap(Width, Height);
Bitmap MyBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel1, pixel2;
for (int x = 0; x < Width - 1; x++)
{
for (int y = 0; y < Height - 1; y++)
{
int r = 0, g = 0, b = 0;
pixel1 = MyBitmap.GetPixel(x, y);
pixel2 = MyBitmap.GetPixel(x + 1, y + 1);
r = Math.Abs(pixel1.R - pixel2.R + 128);
g = Math.Abs(pixel1.G - pixel2.G + 128);
b = Math.Abs(pixel1.B - pixel2.B + 128);
if (r > 255)
r = 255;
if (r < 0)
r = 0;
if (g > 255)
g = 255;
if (g < 0)
g = 0;
if (b > 255)
30
b = 255;
if (b < 0)
b = 0;
bitmap.SetPixel(x, y, Color.FromArgb(r, g, b));
}
}
this.pictureBox1.Image = bitmap;
}
private void menuItem20_Click(object sender, EventArgs e) //锐化效果
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap bitmap = new Bitmap(Width, Height);
Bitmap MyBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel;
//拉普拉斯
int[] Laplacian ={ -1, -1, -1, -1, 9, -1, -1, -1, -1 };
for (int x = 1; x < Width - 1; x++)
for (int y = 1; y < Height - 1; y++)
{
int r = 0, g = 0, b = 0;
int Index = 0;
//int a=0;
for (int col = -1; col <= 1; col++)
for (int row = -1; row <= 1; row++)
{
pixel = MyBitmap.GetPixel(x + row, y + col);
r += pixel.R * Laplacian[Index];
g += pixel.G * Laplacian[Index];
b += pixel.B * Laplacian[Index];
Index++;
}
//处理颜色值溢出
r = r > 255 ? 255 : r;
r = r < 0 ? 0 : r;
g = g > 255 ? 255 : g;
g = g < 0 ? 0 : g;
b = b > 255 ? 255 : b;
b = b < 0 ? 0 : b;
bitmap.SetPixel(x - 1, y - 1, Color.FromArgb(r, g, b));
}
this.pictureBox1.Image = bitmap;
}
31
private void menuItem21_Click(object sender, EventArgs e) //雾化效果
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap bitmap = new Bitmap(Width, Height);
Bitmap MyBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel;
for (int x = 1; x < Width - 1; x++)
for (int y = 1; y < Height - 1; y++)
{
System.Random MyRandom = new Random();
int k = MyRandom.Next(123456);
//像素块大小
int dx = x + k % 19;
int dy = y + k % 19;
if (dx >= Width)
dx = Width - 1;
if (dy >= Height)
dy = Height - 1;
pixel = MyBitmap.GetPixel(dx, dy);
bitmap.SetPixel(x, y, pixel);
}
this.pictureBox1.Image = bitmap;
}
private void menuItem23_Click(object sender, EventArgs e) //关于我们
{
MessageBox.Show("08计一(方武铨&莫志航)倾力制作~", "关于我们");
}
private void button2_Click(object sender, EventArgs e)
{
previous();
}
private void button3_Click(object sender, EventArgs e)
{
next();
}
private void button4_Click(object sender, EventArgs e)
{
delete();
}
private void button5_Click(object sender, EventArgs e)
{
max();
}
32
private void button6_Click(object sender, EventArgs e)
{
min();
}
private void button7_Click(object sender, EventArgs e)
{
right();
}
private void button8_Click(object sender, EventArgs e)
{
left();
}
private void button9_Click(object sender, EventArgs e)
{
close();
}
}
}
5课程体会
在马老师的带领下,我们走过了半年的嵌入式课程的学习,回顾这半年的学习,我们感觉收获良多。由于学院的课程安排,我们想要深入学习嵌入式是不太现实的,所以正如马老师所说,他只能作为一个引导者,指引我们走进嵌入式的世界,深入的研究和探索,都是需要我们日后凭着兴趣和需要继续努力下去。
嵌入式作为后PC时代的杰出代表领域,现在已经深入到各行各业得到极大的应用,今后,想必会发挥出更大的作用和得到更辉煌的发展。希望学院在这方面投入更多的设施和资源,使得更多的同学深入学习嵌入式系统,以便他们抓住后PC时代的发展先机~~
33