制作一个简单的WPF图片浏览器
注:本例选自MSDN样例,并略有改动。
先看效果:
这里实现了以下几个功能:
1. 对指定文件夹下所有JPG文件进行预览
2. 对选定图片进行旋转
3. 对选定图片进行灰度处理
4. 对选定图片进行裁切处理
5. 无限制的恢复功能
6. 类似加入购物车的功能
以下来看看其实现过程。
1. 建立一个ImageFile类,用来读取图像文件:
// ImageFile.cs
using System;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
using System.Text;
namespace PhotoDemo
{
public class ImageFile
{
private String _path;
public String Path { get { return _path; } }
private Uri _uri;
public Uri Uri { get { return _uri; } }
private BitmapFrame _image;
public BitmapFrame Image { get { return _image; } }
public ImageFile(string path)
{
_path = path;
_uri = new Uri(_path);
_image = BitmapFrame.Create(_uri);
}
public override string ToString()
{
return Path;
}
}
}
这里有三个只读属性:Path, Uri和BitmapFrame,分别表示图像图路,通用资源标志符(可以是本地,如c:/myimage/aa.jpg或互联网资源,如: http://www.brawdraw.com/userimages/aa.jpg 等)及图像。BitmapFrame是使用编码、解码器返回或获取图像数据的类,类似于GDI+中的Bitmap类。
2. 建立一个图像列表的类,用于取得指定目录下的所有jpg图像文件:
// PhotoList.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
namespace PhotoDemo
{
public class PhotoList : ObservableCollection<ImageFile>
{
DirectoryInfo _directory;
public DirectoryInfo Directory
{
set
{
_directory = value;
Update();
}
get { return _directory; }
}
public string Path
{
set
{
_directory = new DirectoryInfo(value);
Update();
}
get { return _directory.FullName; }
}
public PhotoList() { }
public PhotoList(DirectoryInfo directory)
{
_directory = directory;
Update();
}
public PhotoList(string path) : this(new DirectoryInfo(path)) { }
private void Update()
{
foreach (FileInfo f in _directory.GetFiles("*.jpg"))
{
Add(new ImageFile(f.FullName));
}
}
}
}
这里有两个公共属性:Directory和Path,用来获取或设置图像目录信息和路径,还有一个Update()私有方法,当文件路径变化时,更新最新的图像文件列表数据。
由于需要对图片做后期处理(如冲/打印,制作成卡片或加工成为T恤衫等),要加入一个类似购物车之类的计算功能(实际的计算功能等未作实现),因此还需要:
3. 建立后期处理的类。由于后期加工均涉及“印”,所以就建立一个名为“印类型”(PrintType)的类:
// PrintType.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace PhotoDemo
{
public class PrintType
{
private string _description;
public string Description { get { return _description; } }
private double _cost;
public double Cost { get { return _cost; } }
public PrintType(string description, double cost)
{
_description = description;
_cost = cost;
}
public override string ToString()
{
return _description;
}
}
}
这里有两个只读属性:描述Description和费用Cost,还对ToString()方法进行了重载。
4. PrintTypeList类,是PrintType列表的集合。
// PrintTypeList .cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace PhotoDemo
{
public class PrintTypeList : ObservableCollection<PrintType>
{
public PrintTypeList()
{
Add(new PrintType("4x6 Print", 0.15));
Add(new PrintType("Greeting Card", 1.49));
Add(new PrintType("T-Shirt", 14.99));
}
}
}
5. 建立一个PrintBase的类:
// PrintBase.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using System.Text;
namespace PhotoDemo
{
public class PrintBase : INotifyPropertyChanged
{
#region public property
private BitmapSource _photo;
public BitmapSource Photo
{
set { _photo = value; OnPropertyChanged("Photo"); }
get { return _photo; }
}
private PrintType _PrintType;
public PrintType PrintType
{
set { _PrintType = value; OnPropertyChanged("PrintType"); }
get { return _PrintType; }
}
private int _quantity;
public int Quantity
{
set { _quantity = value; OnPropertyChanged("Quantity"); }
get { return _quantity; }
}
#endregion public property
public PrintBase(BitmapSource photo, PrintType printtype, int quantity)
{
Photo = photo;
PrintType = printtype;
Quantity = quantity;
}
public PrintBase(BitmapSource photo, string description, double cost)
{
Photo = photo;
PrintType = new PrintType(description, cost);
Quantity = 0;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(String info)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
public override string ToString()
{
return PrintType.ToString();
}
}
}
这里有三个可读写属性:Photo, PrintType和Quantity(表示图片的数量),还设置了一个PropertyChanged委托,用于当属性变更时做相应的事件处理。
6. 继承自PrintBase的三个类:Print, GreetingCard, TShirt, 分别用来打印,制成贺卡及制作T恤衫。
// Print.cs
using System;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
using System.Text;
namespace PhotoDemo
{
public class Print : PrintBase
{
public Print(BitmapSource photo) : base(photo, "4x6 Print", 0.15) { }
}
}
// TShirt.cs
using System;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
using System.Text;
namespace PhotoDemo
{
public class TShirt : PrintBase
{
public TShirt(BitmapSource photo) : base(photo, "T-Shirt", 14.99) { }
}
}
// GreetingCard.cs
using System;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
using System.Text;
namespace PhotoDemo
{
public class GreetingCard : PrintBase
{
public GreetingCard(BitmapSource photo) : base(photo, "Greeting Card", 1.49) { }
}
}
7. "印"的集合:PrintList
// PrintList.cs
using System;
using System.Collections.ObjectModel;
namespace PhotoDemo
{
public class PrintList : ObservableCollection<PrintBase> { }
}
8. 还有就是用于裁切操作的类,由于内容较多,改在下一篇“利用Adorner制作用于图像裁切的选择框”中继续。
9. 窗口主程序的编写,其中包括XAML代码与C#代码。由于内容较多,放在另一篇中详解。
10. 程序的启动、配置等(在WPF中,一般都是app.xml, app.xml.cs中进行的)。
制作一个简单的WPF图片浏览器的更多相关文章
- 如何使用AEditor制作一个简单的H5交互页demo
转载自:http://www.alloyteam.com/2015/06/h5-jiao-hu-ye-bian-ji-qi-aeditor-jie-shao/ 本教程演示如何使用AEditor制作一个 ...
- WPF图片浏览器(显示大图、小图等)
原文:WPF图片浏览器(显示大图.小图等) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/wangshubo1989/article/details ...
- 实例学习SSIS(一)--制作一个简单的ETL包
原文:实例学习SSIS(一)--制作一个简单的ETL包 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习SS ...
- WInform 创建一个简单的WPF应用
(一)创建一个简单的WPF应用 首先,在这里我要说明的是:这里的例子,都是通过控制台程序来创建WPF应用,而非使用现成的WPF模版.因为WPF模版封装了创建WPF应用所需要的各种基本元素,并不利于我们 ...
- TensorFlow练习13: 制作一个简单的聊天机器人
现在很多卖货公司都使用聊天机器人充当客服人员,许多科技巨头也纷纷推出各自的聊天助手,如苹果Siri.Google Now.Amazon Alexa.微软小冰等等.前不久有一个视频比较了Google N ...
- 手把手制作一个简单的IDEA插件(环境搭建Demo篇)
新建IDEA插件File --> new --> Project--> Intellij PlatForm Plugin-->Next-->填好项目名OK 编写插件新建工 ...
- PureMVC和Unity3D的UGUI制作一个简单的员工管理系统实例
前言: 1.关于PureMVC: MVC框架在很多项目当中拥有广泛的应用,很多时候做项目前人开坑开了一半就消失了,后人为了填补各种的坑就遭殃的不得了.嘛,程序猿大家都不喜欢像文案策划一样组织文字写东西 ...
- 自己制作一个简单的操作系统二[CherryOS]
自己制作一个简单的操作系统二[CherryOS] 我的上一篇博客 自己制作一个简单的操作系统一[环境搭建], 详细介绍了制作所需的前期准备工作 一. 一点说明 这个操作系统只是第一步, 仅仅是开机显示 ...
- Expression Blend4经验分享:制作一个简单的图片按钮样式
这次分享如何做一个简单的图片按钮经验 在我的个人Silverlight网页上,有个Iphone手机的效果,其中用到大量的图片按钮 http://raimon.6.gwidc.com/Iphone/de ...
随机推荐
- PHP解决约瑟夫环问题
PHP解决约瑟夫环问题 一.总结 二.PHP解决约瑟夫环问题 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到 ...
- -bash: /usr/local/mysql/scripts/mysql_install_db: /usr/bin/perl: bad interpreter: No such file or directory
安装 MySQL 初始化时,报错如下: [root@hcdb1 ~]# /usr/local/mysql/scripts/mysql_install_db --defaults-file=/etc/m ...
- MFC的CListCtrl的使用与技巧
http://blog.csdn.net/artechtor/article/details/2508070 列表控件可以看作是功能增强的ListBox,它提供了四种风格,而且可以同时显示一列的多中属 ...
- angular自定义管道
原文地址 https://www.jianshu.com/p/5140a91959ca 对自定义管道的认识 管道的定义中体现了几个关键点: 1.管道是一个带有“管道元数据(pipe metadata) ...
- sql server操作远程数据库
--连接远程数据库 EXEC sp_addlinkedserver '服务器ip',N'SQL Server' --登录远程服务器 EXEC sp_addlinkedsrvlogin '服务器ip', ...
- 使用DOT语言和Graphviz绘图(翻译)
Casa Taloyum About Me Blog Archives 使用DOT语言和Graphviz绘图(翻译) Date Wed 26 November 2014 Tags graphviz / ...
- 授人玫瑰 手留余香 --纪念python3.2.3官方文档翻译结束
当你点击看到这篇文章的时候.你已经得到了祝福. 一个来自夜深人静的码农,在2014年5月19号的01:18分.默默为你献上祝福. 希望你.我和他,每个在IT行业中奋斗的人.能找到属于自己一片天空. 在 ...
- LUA整合进MFC代码
这几天研究了一下lua,主要关注的是lua和vc之间的整合,把代码都写好放在VC宿主程序里,然后在lua里调用宿主程序的这些代码(或者叫接口.组件,随便你怎么叫),希望能用脚本来控制主程序的行为.这实 ...
- Tokumx vs Mongodb
Mongodb是一个文档型nosql数据库 採用C++编写 Mongo DB最大的优势在于全部的数据持久操作都无需开发者手动编写SQL语句,直接调用方法就能够轻松的实现CRUD操作. 非常多人觉得mo ...
- jquery-1 jquery几个小实例
jquery-1 jquery几个小实例 一.总结 一句话总结:jquery真的是简单加简便. 1.jquery中改变多个css属性怎么整? 可以链式连接方式,也可以大括号整多个.中间是键值对加引号 ...