FotoVision学习手记(1)

注:本文翻译自微软官网的《FotoVision Desktop Application



FotoVision概述<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

有两种用户:拥有者和浏览者。前者在本地系统上使用桌面应用来修改和管理照片。当照片要发布时,可以通过桌面应用使用一个Web服务来同步Web站点上的文件。通过在SOAP头部中传递Credentials(证书)可以防止非授权用户修改站点上的照片。浏览者通过一个Web浏览器来查看照片。Pocket PC应用使用另一个Web服务来下载和存储照片到本机上,以便可以离线查看。

FotoVision学习手记(1)

桌面应用概述

桌面应用有三个主要功能:管理本地系统中的照片,处理照片,同步网站上的照片。它包含三个不同的面板:左边的管理相册,中间的显示照片,右边的显示照片的细节,还有一些象对比,亮度等工具。实现面板的类都在panes文件夹下,并且都继承自基类BasePane.


FotoVision学习手记(1)

相册和照片存储

FotoVision使用文件系统和XML文件来作为一个简单的数据库。文件系统中的每个文件夹代表一个相册,而文件夹中的每个图象文件代表一个照片。可选的相册和照片元数据信息(例子的描述)储存在相应的XML文件中。

任何引入到应用中的照片都会进行备份,这样原始的照片就不会被修改或者被删除。拷贝被放在MyDocuments/FotoVision/My Albums文件夹下。

缩略图

当检测到新照片或已有照片被修改,FileManager类就会自动产生缩略图。这个类通过移除可疑图象(那些父图象已经被删除的缩略图)来同步缩略图。

PhotoListView类在中间面板上显示照片缩略图。.net framework不支持用户-拖拉的列表视图控件,因此这个类从ListView类继承,并且捕获信息来创建一个用户自拖拉控件。它使用帮助类DropData来作为一个拖拽的目标和源。

FotoVision学习手记(1)

显示图片

PhotoViewer类以完整的大小显示图片。图片被重新调整大小来占据可有的画图区域。

FotoVision学习手记(1)

操纵大图片会是一个很耗费时间的操作。为了达到更好的性能,类中包含了一个工作图片,这是一个全额大小照片的缩小版本。当用户浏览时动作就应用到这个工作图片上,而当保存照片时就应用到全额大小图片上。类中定义了一些常量,这些常量定义了工作图片的分辨率和性能:

FotoVision学习手记(1)'theseaffectthequalityoftheworkingimageandperformance,they
FotoVision学习手记(1)'
donotaffectthequalityofsavedandpublishedphotos(affects
FotoVision学习手记(1)'
whatyouseeonthescreenbutnotwhatissavedtothefilesystem)
FotoVision学习手记(1)
PublicConstWorkingInterpolationModeAs_
FotoVision学习手记(1)InterpolationMode
=InterpolationMode.Bilinear
FotoVision学习手记(1)PublicConstViewingInterpolationModeAs_
FotoVision学习手记(1)InterpolationMode
=InterpolationMode.Bilinear
FotoVision学习手记(1)PublicConstWorkingScaleAsSingle
=0.65F
FotoVision学习手记(1)

为多个图片设置元数据

桌面应用的一个设计目标就是为了能够尽快输入元数据信息。DetailPhote类在一个可伸缩的列表中显示多个照片的细节信息。这使用户可以通过列表中的各个字段框来快速更新元数据。

FotoVision学习手记(1)

这个类是一个用户拖拽的ListBox控件。ListBox中的每项包含了一张照片的元数据。列表可以包含成百照片。这个类使用三个文本框控件并且在适当的时候移动到合适的位置。这样,所有项都好象拥有活动的文本框控件,但实际上只使用了三个窗口指针。不活动区域可以通过用户拖拽来看起来象文本框。

操纵图片

在上传到Web站点前,图片可以进行修改。DetailAction类包含了slider,updown控件和按纽来操纵图片。


FotoVision学习手记(1)

所有的图片操纵都封装在PhotoHelper类中。类大量使用ColorMatrix类,这个类使用一个5*5阵列来操纵图片而不是对图片每个象素进行循环和修改。除次以外,阵列也能够被拼凑并且在一次调用中应用到图片上,这就提供了更好的性能了。这个类支持以下操作:

1) 调整亮度,对比,饱和度,伽马

2) 转换至灰度以及Sepia

3) 旋转和翻转

4) 剪切大小和图象


下面这个例子使用了
PhotoHelper类:

FotoVision学习手记(1)'increasethebrightnessofanimage
FotoVision学习手记(1)
DimimageAsNewBitmap("sample.jpg")
FotoVision学习手记(1)PhotoHelper.AdjustBrightness(image,
50)//调整图片亮度
FotoVision学习手记(1)

FotoVision学习手记(1)
'convertanimagetograyscale
FotoVision学习手记(1)
DimimageAsNewBitmap("sample.jpg")
FotoVision学习手记(1)PhotoHelper.ConvertToGrayscale(image)
//转换至灰度
FotoVision学习手记(1)

FotoVision学习手记(1)
'dobothoperationsinonecall
FotoVision学习手记(1)
DimimageAsNewBitmap("sample.jpg")
FotoVision学习手记(1)Dimm1AsSingle()()
=PhotoHelper.GetBrightnessMatrix(50)
FotoVision学习手记(1)Dimm2AsSingle()()
=PhotoHelper.GetGrayscaleMatrix()
FotoVision学习手记(1)PhotoHelper.AdjustUsingCustomMatrix(image,_
FotoVision学习手记(1)PhotoHelper.CombineMatrix(m1,m2))
//拼凑亮度矩阵和灰度矩阵
FotoVision学习手记(1)

动作列表

ActionItem对象在每次图片被修改时就附加到一个列表(ActionList)中,例如,改变伽玛30%,转换至灰度或者水平翻转图片。这就可以允许动作能够不做(从列表中删除最后一个动作)并且能够把动作应用到不同图片上。如下图所示,当在屏幕上浏览图片时,动作列表就应用到工作图片上,并且当保存,打印和复制到剪切板时就应用到原始图片上。

FotoVision学习手记(1)

OptimizeActions类通过将尽可能多个动作结合进一个单个动作来对动作进行优化。例如,颜色阵列动作亮度,对比,饱和度,灰度以及sepia都可以整合进一个单一动作中。另一个例子是多个旋转,执行3次左旋转和一次右旋转是一样的。你可以右键一个图片,选择“Properties”,”Actions”来查看当前的动作列表。

FotoVision学习手记(1)

使用JPEG图片

代码中包含两个帮助类来方便JPEG图片的使用。

分辨率

当保存图片时,.net framework中的Image类不允许你指定分辨率,至少没有任何一个Save方法有任何分辨率参数。你可以使用EncoderParameterImage这两个类创建不同分辨率的JPEG图片。EncoderParameter类允许你指定介于1(低分辨率,高压缩率)和100(高分辨率,低压缩率)之间的分辨率。Image类默认使用的分辨率近似75JpegQuality类将这进行了封装,你可以如下调用:

FotoVision学习手记(1)'saveahighqualityjpegimage
FotoVision学习手记(1)
JpegQuality.Save("sample.jpg",image,90)
FotoVision学习手记(1)
FotoVision学习手记(1)
'savealowqualityjpegimage
FotoVision学习手记(1)
JpegQuality.Save("sample.jpg",image,30)
FotoVision学习手记(1)

可交换的图片文件格式

另一个.net framework不直接支持的地方是可交换图片文件(EXIF)数据。这是嵌入到图片文件内部的额外元数据信息;几乎所有的数码像机都存储EXIF信息。

当你使用Image类来复制一个图片时这个信息就会丢失。在保存图片前你必须从PropertyItems集合中手动复制集合中的各项。Exif类封装了这个功能,这样你就可以在你的图片中维护EXIF数据。除次以外,类还可以抽取常见的EXIF标记,象照相机模型,暴光时间和用户评语等。

FotoVision学习手记(1)



反馈机制

桌面应用程序有三种反馈机制:快速,中度,慢速。目标是以为用户提供足够的反馈。适当的反馈可以使用户的感知时间看起来更少,或者说当用户在屏幕上有有趣的东西看时不会发火。

快速反馈


当一个操作只需要几秒钟时就发生快速反馈。在操作发生时显示一个等待光标并且应用程序锁定。用户可能感觉不到应用程序正忙。

中度反馈

当操作时间长于1秒而小于1分就会发生中度反馈。在状态栏的左边会显示一个等待图标和信息,而右边会显示一个进度条。应用程序会锁定至操作结束。

FotoVision学习手记(1)

桌面应用会调用DoEvents方法使得它可以重画,并且对WndProc方法进行重写以便只有画图信息会被处理。

慢速反馈

若任务需要耗费很长的时间完成的话就会发生慢速反馈。在应用中有两种很耗时的操作:当照片发布时(调整大小),以及当文件上传到网站上。

当这些操作进行时会显示一个进度条和其他信息。这样用户就可以知道系统正在进行的操作并且知道还剩余多少时间。在调整照片大小的时候应用程序会阻塞住,但当上传文件到站点时却不会被阻塞(用户还是可以删除照片,修改照片等)。

FotoVision学习手记(1)

上传文件到Web站点

用于上传的代码在upload文件夹下,应用中有两个部分会上传文件到Web站点:发布文件和上传文件。

Publish类通过对图片进行复制并且以一定的大小和JPEG分辨率(在SettingsForm类中指定)保存来准备要上传的图片。通过使用Hash值来对每个文件进行唯一识别,这样就使得只有修改过的图片才会调整大小。操作在一个工作线程中执行并且会引发事件来更新用户接口。

当发布操作完成后,Upload类通过一个Web服务来对站点上的文件和本地系统上的文件进行同步。这包括相册,照片和元数据XML文件。它会从Web站点下载Hash值,这个值可以唯一识别站点上的文件,这样它就可以决定要上传的最小数据量。这个操作也在一个工作线程中执行并且会引发事件来更新用户接口。

UploadForm类显示从两个工作线程中获取的信息,并且在更新用户界面元素之前通过调用Control.Invoke来对数据进行混淆。在使用Web服务时需要密码,密码以加密值的形式存储在应用程序的配置文件中。Upload类从配置文件中读取值(Settings),通过DataProtection类的Data Protection接口来对值进行解密,对数据进行Hash(Hash),并且在一个客户端的SOAP头部中储存这个值。下图显示了Upload类:

FotoVision学习手记(1)

打印

如下图,通过使用Windows XP图片打印向导来对打印图片。这个向导在系统文件photowiz.dll中实现。Print类封装在打印代码。

FotoVision学习手记(1)

小技巧

释放bitmap对象


调用Dispose来释放Bitmap对象,否则将会阻塞并且若你尝试删除或者重写bitmap文件时会抛出一个异常。


FotoVision学习手记(1)'rotateanimage,callDisposewhendone
FotoVision学习手记(1)
DimimageAsNewBitmap("sample.jpg")
FotoVision学习手记(1)image.RotateFlip(RotateFlipType.Rotate90FlipX)
FotoVision学习手记(1)image.Save(
"newsample.jpg",Imaging.ImageFormat.Jpeg)
FotoVision学习手记(1)image.Dispose()
FotoVision学习手记(1)