原文:制作一个简单的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图片浏览器的更多相关文章

  1. 如何使用AEditor制作一个简单的H5交互页demo

    转载自:http://www.alloyteam.com/2015/06/h5-jiao-hu-ye-bian-ji-qi-aeditor-jie-shao/ 本教程演示如何使用AEditor制作一个 ...

  2. WPF图片浏览器(显示大图、小图等)

    原文:WPF图片浏览器(显示大图.小图等) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/wangshubo1989/article/details ...

  3. 实例学习SSIS(一)--制作一个简单的ETL包

    原文:实例学习SSIS(一)--制作一个简单的ETL包 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习SS ...

  4. WInform 创建一个简单的WPF应用

    (一)创建一个简单的WPF应用 首先,在这里我要说明的是:这里的例子,都是通过控制台程序来创建WPF应用,而非使用现成的WPF模版.因为WPF模版封装了创建WPF应用所需要的各种基本元素,并不利于我们 ...

  5. TensorFlow练习13: 制作一个简单的聊天机器人

    现在很多卖货公司都使用聊天机器人充当客服人员,许多科技巨头也纷纷推出各自的聊天助手,如苹果Siri.Google Now.Amazon Alexa.微软小冰等等.前不久有一个视频比较了Google N ...

  6. 手把手制作一个简单的IDEA插件(环境搭建Demo篇)

    新建IDEA插件File --> new --> Project--> Intellij PlatForm Plugin-->Next-->填好项目名OK 编写插件新建工 ...

  7. PureMVC和Unity3D的UGUI制作一个简单的员工管理系统实例

    前言: 1.关于PureMVC: MVC框架在很多项目当中拥有广泛的应用,很多时候做项目前人开坑开了一半就消失了,后人为了填补各种的坑就遭殃的不得了.嘛,程序猿大家都不喜欢像文案策划一样组织文字写东西 ...

  8. 自己制作一个简单的操作系统二[CherryOS]

    自己制作一个简单的操作系统二[CherryOS] 我的上一篇博客 自己制作一个简单的操作系统一[环境搭建], 详细介绍了制作所需的前期准备工作 一. 一点说明 这个操作系统只是第一步, 仅仅是开机显示 ...

  9. Expression Blend4经验分享:制作一个简单的图片按钮样式

    这次分享如何做一个简单的图片按钮经验 在我的个人Silverlight网页上,有个Iphone手机的效果,其中用到大量的图片按钮 http://raimon.6.gwidc.com/Iphone/de ...

随机推荐

  1. Launcher Activity在开机时重新启动两次解决的方法

    今天在看log的时候发现,Launcher activity会被onDestroy掉一次.然后再重新启动. 可能原因推測: 1.横竖屏切换 2.MCC MNC等Configuration改变引起的 M ...

  2. Android 底部TabActivity(0)——开篇(界面分析|系列文章文件夹)

    当下主流的软件没有一个统一明白的风格,App框架什么样的都有,但个人钟情于页面底部Tab分签架构,移动设备的屏幕尽管越来越大,可是显示的内容还是有限,为了能展示很多其它的内容,方便简洁的操作习惯中Ta ...

  3. 【52.49%】【codeforces 556A】Case of the Zeros and Ones

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  4. swift学习第二天:swift中的基本数据类型

    一:swift基本数据类型 Swift中的数据类型也有:整型/浮点型/对象类型/结构体类型等等 先了解整型和浮点型 整型 有符号 Int8 : 有符号8位整型 Int16 : 有符号16位整型 Int ...

  5. python opencv3 —— findContours

    findContours 是 opencv 下的轮廓提取函数. 1. api 分析 findContours(image, mode, method[, contours[, hierarchy[, ...

  6. tomcat 启动项目时出现 ZipException: error in opening zip file

    错误情况 项目用 maven 打好 war 包后放到 tomcat 下,启动 tomcat,出现以下错误 3-Nov-2017 12:21:44.346 严重 [localhost-startStop ...

  7. Ubuntu su 认证失败

    在使用Ubuntu作为开发环境时经常须要在全局安装一些依赖框架等.这个时候就经常须要用到root权限.可是在Ubuntu下第一次使用su命令时会提示认证失败:查找资料后发现Ubuntu下root权限默 ...

  8. 如何使用Name对象,包括WorkspaceNames和DatasetNames

    转自chanyinhelv原文 如何使用Name对象,包括WorkspaceNames和DatasetNames 第一原文链接 该博主还有很多有关arcgis二次开发的不错的文章. 如何使用Name对 ...

  9. [Angular] Difference between ViewChild and ContentChild

    *The children element which are located inside of its template of a component are called *view child ...

  10. error: invalid abbreviation code [25] for DIE at 0x0000003e in Assertion failed: (*offset_ptr == end_prologue_offset), function ParsePrologue, file /S

    error: invalid abbreviation code [25] for DIE at 0x0000003e in '/Users/mac/Desktop/MYiosfiles/test/X ...