FotoVision学习手记(1)

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

FotoVision概述

 

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

桌面应用概述

 

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


fotovision_desktop_fig02.png

相册和照片存储

 

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

 

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

 

缩略图

 

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

 

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

fotovision_desktop_fig03.png

显示图片

 

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

fotovision_desktop_fig04.png

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

'  these affect the quality of the working image and performance, they
'
 do not affect the quality of saved and published photos (affects 
'
 what you see on the screen but not what is saved to the file system)
Public Const WorkingInterpolationMode As _
  InterpolationMode 
=  InterpolationMode.Bilinear
Public Const ViewingInterpolationMode As _
  InterpolationMode 
=  InterpolationMode.Bilinear
Public Const WorkingScale As Single 
=   0.65F

为多个图片设置元数据

 

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

  fotovision_desktop_fig05.png

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

 

操纵图片

 

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


fotovision_desktop_fig06.png

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

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

2)              转换至灰度以及Sepia

3)              旋转和翻转

4)              剪切大小和图象


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

'  increase the brightness of an image
Dim image As New Bitmap( " sample.jpg " )
PhotoHelper.AdjustBrightness(image, 
50 ) // 调整图片亮度

'  convert an image to grayscale
Dim image As New Bitmap( " sample.jpg " )
PhotoHelper.ConvertToGrayscale(image)
// 转换至灰度

'  do both operations in one call
Dim image As New Bitmap( " sample.jpg " )
Dim m1 As Single()() 
=  PhotoHelper.GetBrightnessMatrix( 50 )
Dim m2 As Single()() 
=  PhotoHelper.GetGrayscaleMatrix()
PhotoHelper.AdjustUsingCustomMatrix(image, _
   PhotoHelper.CombineMatrix(m1, m2))
// 拼凑亮度矩阵和灰度矩阵

动作列表

 

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

fotovision_desktop_fig07.png

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

使用JPEG图片

 

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

 

分辨率

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

'  save a high quality jpeg image
JpegQuality.Save( " sample.jpg " , image,  90 )

'  save a low quality jpeg image
JpegQuality.Save( " sample.jpg " , image,  30 )

可交换的图片文件格式

 

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

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

fotovision_desktop_fig09.png



反馈机制

 

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

 

快速反馈


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

中度反馈

     

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

fotovision_desktop_fig10.png

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

 

 

慢速反馈

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

 

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

fotovision_desktop_fig11.png

上传文件到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_desktop_fig12.png

 

      打印

     

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

fotovision_desktop_fig13.png

 

小技巧

 

释放bitmap对象


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


'  rotate an image, call Dispose when done
Dim  image  As   New  Bitmap( " sample.jpg " )
image.RotateFlip(RotateFlipType.Rotate90FlipX)
image.Save(
" new sample.jpg " , Imaging.ImageFormat.Jpeg)
image.Dispose()    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值