Gallery Server Pro ----用于分享相片,视频,音频及其他媒体的ASP.NET相册[Carol]

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:

原作者: Roger Martin

Gallery Server Pro下载

Gallery Server Pro是一个完整,稳定的,用于分享相片,视频,音频及其他媒体的ASP.NET相册,这一文章展示了其整体的风格及主要特征.

gs_screenshot1_large.jpg

导言

Gallery Server Pro是强大便捷的ASP.NET网络应用程序,它使你能够在网络上分享,处理相片,视频,音频及其他的文件.

.稳定,产品准备就绪

.可以使用任何浏览器将媒体文件整理到相册中,可以随意添加,编辑,删除,旋转,编排,复制以及移动.

.使用一键同步和ZIP下载功能可简便地添加成千上万的文件.缩略版和压缩版会自动被创制.

.强大的用户安全,具有灵活的每册粒度?

.与DotNetNuke及其他框架合为一体,以提供一个高级的媒体相册
.图片元数据抽取?支持以下格式: EXIF, XMP, tEXt, IFD, 以及 IPTC.

.搜寻功能询问标题,字母,文件名,以及图片元数据.

.图片上附带有自己的文本和(或)图片的水印

. AJAX更丰富的灵活的界面

. 便捷的基于网络的安装

. 用SQL Server 2000或更高的级别作为数据库.支持MSDE 2000 和SQL Server 2005 Express.

.使用 ASP.NET会员供应商,以便你能够融合?现有帐户,包括Active Directory.

.数据输入使用供应商模式,它允许使用其他的数据库例如MySQL, MS Access, 或 Oracle来代替SQL Server.

.托管代码全部用C# and ASP.NET 2.0写.

.在开放源码GNU General Public License下发放源代码.

.所有的网页目标XHTML 1.0 Strict 和 CSS 2.1标准来确保兼容性的最大化.

你可以使用online demo of Gallery Server Pro来感受一下它的兼容性, www.galleryserverpro.com提供了一个预编译版本以及一些其他的资料和一个支持论坛.

背景

这一项目源于2002年我想把照片放到网络上进行分享的欲望.我想我的照片保留在我自己的服务器上,而不是其他人的服务器上,如EasyShare或Shutterfly的.由于那时没有可供选择的免费解决方案,所以就自己写了.

2006年1月我向世界推出了第一版,反响非常好, 下载次数超过了30,000次.2006年及2007年大多数时间我都在研究第二版, 在使用新的ASP.NET 2.0特征的组中重新写代码.

它包括了ASP.NET的Membership, Roles, Profiles, generics,the data provider model,以及几个著名的设计模式(strategy, iterator, factory, template method, and composite)

在这篇文章中,我将展示Gallery Server Pro的整体设计及主要特点.如果想知道更多,这里几个主题会有帮助:

.运用网络相册来分享相片,视频,音频及其他文件.

.使用了ASP.NET的Membership, Roles and Profile API

.使用综合设计模式来无限处理等级关系,一般是媒体物和相册,但它也应用于雇员/上司关系, 条例的材料,资料/目录关系及其他相似的结构项目.

.何时及如何来使用策略设计模式.

.在ASP.NET 2.0下使用数据提供模式.

.运用灵活的技术把明显的HTML提交到基于浏览器类型及要提交的对象类型的浏览器

.运用 .NET 2.0技术和新的.NET 3.0的WPF从图片中截取元数据

使用Gallery Server Pro

Gallery Server Pro是一个完全功能性及稳定性的用于产品使用的网络应用程序.

1. 在本文中下载及编译源代码或者下载编译过的版本.然后将编译的web应用程序部署到目的web服务器.

2. 运用Internet Information Services (IIS) Manager来配置目录作为web应用程序. 保证这一应用在ASP.NET 2.0下运行.

3. 如果使用早于IIS 7的IIS版本,确保错误的文件设置到default.aspx. IIS 7用户可以跳过这一步.

4. 使用Windows Explorer将"modify" config 和mediaobjects目录的权限应用到IIS用户帐号。

5. 使用SQL管理工具如SQL Management Studio (SQL Server 2005)或 SQL Enterprise Manager (SQL Server 2000)来创建一个新的空的数据库.

6. 使用网络浏览器导航到Installer目录来启动基于网络的安装.例如, 你安装文件到C:\inetpub\wwwroot\gs\ ,那网址就是http://localhost/gs/installer/

7. 按照安装向导的步骤进行安装.完成后,你就可以使用Gallery Server Pro了.

Gallery Server Pro储存了媒体,如相册中的照片,视频,音频和文件等.这些文件和相册被储存在一个名为mediaobjects的在网络应用下的目录中(它可以在网络服务器上任意改变地址).一个相册只是一个目录,所以储存一个名为Vacation Photos的相册与目录的名字非常相似.

要添加媒体物有两个重要的技巧:

1. 上传一个包括媒体文件的ZIP文件. 如果这一ZIP文件包含目录,那它就转变为相册.

2. 将你的媒体文件复制到媒体目录中, 然后在Gallery Server Pro中启动同步?.

添加媒体物时,会发生以下步骤:

1. 文件保存到媒体物目录中.(如果通过同步技术来添加媒体物的话,这一步骤就已经完成了)

2. 缩略照片被创建并保存到硬盘.

3. 图片,压缩的宽带版本?被创建,元数据,如照相机模型和快门速度就被摘取了.

4. 数据库里将添加一个记录来代表这一媒体物.

媒体物通过HTTP处理器流向浏览器.下面您可以看到一张照片及一段视频正在被演示.如果水印有效的话,水印会在照片及视频上传前被添到有记忆版本的照片上.

clip_image001clip_image002

如果你点击媒体物上方的视图元数据工具栏,就会弹出一个DIV窗口来演示图象的元数据,就如以下所示:

clip_image003

默认状态下每个人都可以浏览这个媒体物,但是你必须登陆来修改相册或媒体物。授权修改数据由相册的许可的类型?来配置。比如你可以建立用户Soren使其允许修改相册Soren's photos另外一个用户Margaret可以被编辑允许修改相册Margaret's photos每个用户都可以管理自己的相册,但不能编辑在他们域名之外的相册。

想要从一个终端用户的视角更多地了解如何来使用Gallery Server Pro,请阅读Administrator's Guide。不然请继续往下了解其架构及编程技术。

解决方案架构

这一下载的Visual Studio解决方案包括十个项目。

项目名字 

描述

gsweb

UI layer - ASP.NET 2.0 网络应用.

TIS.GSP.WebControls

包括用于网络应用的客户定制服务控制

TIS.GSP.Business

商务层逻辑

TIS.GSP.Provider

数据供应者。界定了数据层必须遵循的合同

 

TIS.GSP.Business.Interfaces

界定了在这个方案中使用的所有接口

TIS.GSP.ErrorHandler

提供了错误处理的支持

TIS.GSP.Configuration

提供了读/写程序进入储存于配置文件galleryserverpro.config的设置

TIS.GSP.Business.Wpf

通过截取能够在.NET 3.0. 中运用的新的WPF级来提供升级的图象元数据。当不在.NET 3.0时,就包含在一个分离的项目中,通过某种优雅降解的方式的反应来引用。???

TIS.GSP.Data

数据层逻辑。提供读/写进入到储存在SQL服务器的数据

TracingTools

 

提供追查的支持

用户管理和安全

用户帐户是通过ASP.NET membership,role,及profile APIs来管理的.默认状态下,Gallery Pro Sever为用户提供SqlMembershipProvider,为role提供SqlRoleProvide,为profile提供SqlProvider。然而由于提供的模版的灵活性,你可以使用任何拥有会员的数据库。比如,你可以用ActiveDirectoryMembershipProvider 将Gallery Server Pro 插入已存在的Active Directory使用者的base. Administrator's Guide包括用于会员配置的一个区域以提供更多的信息。

媒体,相册及其组合模式

每一媒体(包括照片,视频等)都储存于相册中。相册可以放在另一个相册中,无层级

数量的限制。类似资料和目录在硬盘上储存。

相册和媒体物有许多共同点。他们都有例如这样的属性:Id, Title, DateAdded,及FullPhysicalPath;他们也有同样的方法,如 Save, Delete, Copy, Remove, and ValidateTitle.这是使用合成模式的理想环境,在这一环境中,常见功能被定义在基础物体中?。首先来界定两个接口 IGalleryObject 和IAlbum:

clip_image001[1]

IAlbum接口继承了IGalleryObject,随后又添加了用于相册的特定的一种方法和一些属性。然后创造了抽象基本类?GalleryObject。它使用了IGalleryObject接口,并且提供了相似于相册和媒体物的默认行为。比如,以下是Title属性:

public string Title
{
  get
  {
    VerifyObjectIsInflated(this._title);
    return this._title;
  }
  set
  {
    value = ValidateTitle(value);

    this._hasChanges = (this._title == value ? _hasChanges : true);
    this._title = value;
  }
}

既然常见功能被定义在抽象基本类中,我可以创建具体的类来代表相册,图象,视频,音频,以及其他的媒体物:

 

clip_image001[3]

运用这一方法,重复代码将极少出现,结构具有可维护性,并且使用方便。比如,当Gallery Server Pro想要为相册里的所有物体展示标题及缩略图时,有可能出现任何子相册,图片,视频,音频以及其他文件的组合。不过我不必担心所有不同的类和about casting问题。我所需要的只是以下代码:

// Assume we are loading an album with ID=42
IAlbum album = Factory.LoadAlbumInstance(42, true);
foreach (IGalleryObject galleryObject in album.GetChildGalleryObjects())
{
  string title = galleryObject.Title;
  string thumbnailPath = galleryObject.Thumbnail.FileNamePhysicalPath;
}
 

完美,不是吗? 但是当两类物体间的功能存在细微的差别时会发生什么?例如,Gallery Server Pro强制要求一个相册的标题最大长度为200个字符,一个媒体物(图片,音频等)的标题最大长度为1000个字符。两类物体都需要Title属性, 但是验证却是不同的。 那是否意味着我们必须把Title 属性从基本类中移除,把它放到衍生类中? 不是的!参照我们之前看的代码中对于Title的属性界定,注意在设置中有一个对ValidateTitle 的call。以下是 ValidateTitle 在GalleryObject类中的样子:

protected virtual string ValidateTitle(string title)

{

// Validate that the title is less than the maximum limit. Truncate it if necessary.

int maxLength = 

GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().DataStore.MediaObjectTitleLength;

if (title.Length > maxLength)

{

title = title.Substring(0, maxLength).Trim();

}

return title;

}

这一程序是虚拟的,如果有必要,允许衍生层级凌驾于它之上。实际上,这正是Album 层所做的:

protected override string ValidateTitle(string title)

{

int maxLength = 

GalleryServerPro.Configuration.ConfigManager.GetGalleryServerProConfigSection().DataStore.AlbumTitleLength;

if (title.Length > maxLength)

{

title = title.Substring(0, maxLength).Trim();

}

return title;

}

最终结果是在基层里有一个基础的执行为大多数案例提供功能,相册特定的代码包括在Album层级中。没有任何复制的代码,逻辑被完美地包裹。颇为完美!

使用策略模式用以持续的数据储存

我们刚刚看了当要改变其行为时如何在基本类中越过一种方法。当要保存相册及媒体物到数据库时我原本可以做一些类似的。在GalleryObject 层中的Save方法本可以被界定为虚拟的,我也原本可以在衍生类中越过这一方法。但是由于Image, Video, Audio, 和GenericMediaObject类都代表了被储存在同一个表里的物体(如媒体物),那可能意味着在所有四个类中写同样的代码,除了Album类。

我可以在GalleryObject类中通过为Save法提供一个默认操作来消除复制代码问题。在那个方法中,我保存到媒体物表格,然后依靠Album类来越过这一行为,很像我们对ValidateTitle的操作。然而这是把大量不真正属于那里的行为放到基本类中。我们必须将基本类限制于仅包含适用于ALL衍生物的状态和行为。

你也许会争论:我为ValidateTitle方法提供默认操作,在Album类中越过它时,我违反了这一原则。完全正确。以下是我的自圆其说:在每个衍生类中操作标题验证会创造不可取的复制代码,然后运用策略模式来重构它等于是矫枉过正。这些不是硬性规定。建构一个运用就如科学那样有技术性,你必须权衡每一步的正反意见。

回到我们对于持续的数据储存的挑战中,我想到的方法是用策略模式去包裹?行为。首先,界定接口ISaveBehavior:

public interface ISaveBehavior { void Save(); }

然后我写了操作这一接口的两个类:AlbumSaveBehavior以及MediaObjectSaveBehavior.这一保存方法小心地将物体保留到硬盘和数据库。比如,以下是AlbumSaveBehavior的save方法:

public void Save()

{

if (this._albumObject.IsVirtualAlbum)

return; // Don't save virtual albums.

// Save to disk.

PersistToFileSystemStore(this._albumObject);

// Save to the data store.

GalleryServerPro.Provider.DataProviderManager.Provider.Album_Save(this._albumObject);

}

注意这里有对PersistToFileSystemStore的需求,它是一个私人方法用以确保这个相册存在对应的目录。随后也有对Provider 类的Album_Save方法的需求,它坚持把数据保存到SQL 服务器的gs_Album表。如果你使用数据提供而不是默认的SqlDataProvider,那这一方法就代表了那个服务。我们将在下文中讨论数据供应。

好了,把数据储存到数据库我们有两个类——一个用于储存相册,一个用于储存媒体物。我们该怎样从GalleryObject基本类中引用合适的Save方法呢?

回忆一下,GalleryObject类是抽象的,所以它永远不能被例示出来。但是我们可以用Album, Image, Video, Audio, 或 GenericMediaObject类来具体示例。每个层的建构者指定了合适的储存行为。例如,在Album类中我们有:

this.SaveBehavior = Factory.GetAlbumSaveBehavior(this);

GetAlbumSaveBehavior方法刚刚回到了AlbumSaveBehavior类的一个例子:

public static ISaveBehavior GetAlbumSaveBehavior(IAlbum albumObject)

{

return new AlbumSaveBehavior(albumObject);

}

GalleryObject 类的SaveBehavior属性是ISaveBehavior类型。既然两个类都运用这个接口,我们可以指定任何一个层的例子到这一属性。

GalleryObject 类中Save方法在SaveBehavior属性中简单地叫Save方法。我们不清楚这一属性是AlbumSaveBehavior 或MediaObjectSaveBehavior的例子,但这无关紧要。最重要的是每一类都知道如何来保存其设计的物体。

这是一个运用策略模式的例子。具体而言,策略模式就是被包裹以及能够相互转变的系。在我们的例子中,我们有两种保存的行为,它们可以自我包含而且都可以被指定到同一个属性(可相互改变)。它是一个有力的模式,也有许多用处。

向视频,图片,音频及更多提供HTML

由于浏览器都能识别<img>标签,所以在网页浏览器上展示图片是容易的。但是该怎样操作一个同样包括视频,音频以及其他例如Adobe PDF 或 Microsoft Word 资料的gallery呢?浏览器本身是不能展示任何视频和音频或天然地展示任何资料的,除了一些基本类型,像HTML, TXT以及可能 XML。这些物体的类型需要plug-ins,如果有的话,你也不可能对到底是什么plug-ins安装在用户的浏览器中作任何猜想。而且Gallery Server Pro是灵活的,这样管理者就能定制由提供的Gallery Server Pro HTML结果。例如,一些用户更喜欢视频资料有<object>标签,这样就可以通过XHTML校验,但其他人也许喜欢<embed>标签用以最大的背景兼容。最后,不同的浏览器需要不同的句法,新版的浏览器不断被开发,有可能会突破现在所运作的。

这一解决方案是使用储存在配置资料的HTML模版和由ASP.NET提供的自动浏览两者的结合。配置资料galleryserverpro.config(储存在config directory)包括用以每个主要的媒体物类型的HTML模版。例如,为一个图片提供HTML是非常直接的。这是galleryserverpro.config的相关输入:

<galleryObject>

<mediaObjects>

<mediaObject mimeType="image/*">

<browsers>

<browser id="default" htmlOutput="<div class="op1"

><div class="op2"><div class="sb">

<div class="ib"><img id="mo_img" 

src="{MediaObjectUrl}" class="{CssClass}" 

alt="{TitleNoHtml}" title="{TitleNoHtml}" 

style="height:{Height}px;width:{Width}px;" />

</div></div></div></div>" />

</browsers>

</mediaObject>

...

</mediaObjects>

</galleryObject>

这一mediaObject标签规定了内标签运用于image/* MIME 类型。asterisk (*)意味着它将匹配所有的图片,如image/jpg, image/jpeg, 和 image/gif。现在让我们进一步来看一下浏览器标签中htmlOutput属性中有什么:

<div class="op1">

<div class="op2">

<div class="sb">

<div class="ib">

<img id="mo_img" src="{MediaObjectUrl}" 

class="{CssClass}" alt="{TitleNoHtml}" 

title="{TitleNoHtml}" style="height:{Height}px;width:{Width}px;" />

</div>

</div>

</div>

</div>

注意:在配置资料<, >和htmlOutput属性中的字母都被遗漏了&lt;, &gt; and &quot;但我在这里省略是为了读起来更加简便。

环绕在<img>标签周围四个<div>标签用以支持在每个图片周围出现的下降阴影和边界。但是在括号里的东西是什么,就如{MediaObjectUrl}?那些是在运行时间被动态生成的内容所代替的placeholders。比如,{Height}被图片的高度所替代。在Administrator's Guide中能找到这些placeholders的完整清单和描述。

当Gallery Server Pro使用上述的模板向浏览器提供一个图片,它以类似下面的东西结束:

<div class="op1">

<div class="op2">

<div class="sb">

<div class="ib">

<img id="mo_img" 

src="http://www.codeproject.com/gs/handler/getmediaobject.ashx?

moid=2064&aid=169&mo=D%3A%5Cgs%5Cmediaobjects%

5CzThumb_100_1768.jpeg&mtc=1&dt=1" alt="Grand Canyon" 

style="width:86px;height:115px;" />

</div>

</div>

</div>

</div>

如果愿意,你可以稍微调整一下这个模板来改变如何提供<img>标签。比如,你想使用宽度和高度属性而不是风格属性,请将配置资料更新到如下:

<browser id="default" htmlOutput="<div class="op1"><div class="op2">

<div class="sb"><div class="ib">

<img id="mo_img" src="{MediaObjectUrl}" 

class="{CssClass}" alt="{TitleNoHtml}" 

title="{TitleNoHtml}" width="{Width}" height="{Height}" />

</div></div></div></div>" />

图片提供是非常直接的,如果我们所做的完全只是展示图片,那在此展示的技术就有点小题大做了。但一旦我们接触更加复杂的媒体类型它就变得有用了。例如,让我们来看一下galleryserverpro.config的描述视频是怎样提供的相关部分:

Collapse

<mediaObject mimeType="video/*">

<browsers>

<browser id="default" 

htmlOutput="<object type="{MimeType}" 

data="{MediaObjectUrl}" style="width:{Width}px;height:{Height}px;" >

<param name="src" value="{MediaObjectUrl}" /> 

<param name="autostart" value="{AutoStartMediaObjectInt}" />

</object>" />

<browser id="ie" htmlOutput="<object 

type="{MimeType}" data="{MediaObjectUrl}" 

style="width:{Width}px;height:{Height}px;"> 

<param name="src" value="{MediaObjectUrl}" /> 

<param name="autostart" value="{AutoStartMediaObjectText}" />

</object>" />

</browsers>

</mediaObject>

<mediaObject mimeType="video/quicktime">

<browsers>

<browser id="default" htmlOutput="<object 

type="{MimeType}" data="{MediaObjectUrl}" 

style="width:{Width}px;height:{Height}px;"> 

<param name="autoplay" value="{AutoStartMediaObjectText}" />

<param name="controller" value="true" />

<param name="pluginurl" 

value="http://www.apple.com/quicktime/download/" />

</object>" />

<browser id="ie" htmlOutput="<object 

classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" 

codebase="http://www.apple.com/qtactivex/qtplugin.cab" 

style="width:{Width}px;height:{Height}px;"> 

<param name="src" value="{MediaObjectUrl}" /> 

<param name="autoplay" value="{AutoStartMediaObjectText}" /> 

<param name="controller" value="true" /> 

<param name="pluginspage" 

value="http://www.apple.com/quicktime/download/" />

</object>" />

</browsers>

</mediaObject>

注意这里有两个mediaObject元――一个用以规定MIME 类型 video/*,另一个规定video/quicktime。在video/* 下的HTML模板处理提供视频的所有通用个案。由于第二个元需要不同的HTML,因此它用以处理QuickTime视频的更多具体案例HTML。比如,如果AVI资料需要定制HTML,你可以添加其他的mediaObject元。

进一步看一下 video/*模板内的浏览器作品?。这里有两种浏览器元——一个是id="default",另一个是id="ie"。Id属性独特地定义了浏览器元,而且它必须与浏览器内部的标识符相匹配,就如.Net Framework's浏览器界定资料中规定的那样。请看http://msdn.microsoft.com/msdnmag/issues/06/10/ExtremeASPNET/fig05.gif由.Net Framework 2.0识别的id等级表。

这两个元为默认浏览器明确了一个HTML,为IE明确了另一个HTML。如果仔细看一下HTML模板,你会发现它们是很相似的,除了一个明确AutoStartMediaObjectInt ,而另一个明确AutoStartMediaObjectText。那是因为IE需要autostart参数作为文本,像"true" 或 "false",而其他的浏览器需要一个数值(1 for true, 0 for false)。

比如你发现由于HTML 的非兼容性,Safari浏览器不能正常运作,你可以添加一个浏览器元id="safari"。然后用Safari要求的句法添加HTML模板,这样就完成了。Gallery Server Pro 和ASP.NET自动地辨认浏览器类型然后发送正确的HTML。

数据供应商模式

ASP.NET 2.0的一个最新特征就是供应商模式。在Gallery Server Pro中,我曾经用供应商模式将用以读写资料的API界定到数据库。只要那里写有供应商程序,你就可以使用数据库的任何资源。Gallery Server Pro 2.0包括SqlDataProvider,允许其与SQL服务器进行互动。还可以写其他的使用MySQL, Oracle, Microsoft Access,或者甚至是 XML 资料作为数据库的供应商。

下面的图表演示了SqlDataProvider类 和 DataProvider类,即使名字听上去像官方的.NET Framework类,这些是我特别为Gallery Server Pro而写的。DataProvider是抽象的继承于Microsoft .NET Framework System.Configuration.Provider.ProviderBase的类。它不包括任何的行为;它只是界定了必须用"real"数据供应商来操作的方法,在这个案子中就是SqlDataProvider。在Gallery Server Pro中所有的数据输入都通过SqlDataProvider中的其中一个方法(除非用户帐户功能通过其他的供应商--membership, roles, 及 profile)。

clip_image001[5]

要用另外的如MySQL, Oracle, Microsoft Access或其他的数据库,写一个新的继承DataProvider抽象基本类的类。你可以在一个新的项目中做,也可以通过在TIS.GSP.Data项目中添加一个新的类。如果你用例如Visual Studio的工具,它会自动界定所有必须要被执行的方法。比如,以下是用以删除一个相册所用方法的框架:

public override void Album_Delete(IAlbum album)

{

} 

当某个相册需要被删除时Gallery Server Pro会呼叫这个方法。就如这个服务器供应商一样,写一个代码用以从你的数据库中删除相册记录是你的工作。怎样做就由你来定。

注意:参照SqlDataProvider类中的代码用以确保你提供相似的行为。比如,在删除一个相册的时候,SqlDataProvider类执行一个已存储的程序来递归删除这一特定相册的所有子相册。你的服务器供应商应相似操作。

一旦你已经操作了所有的方法并且编写好了代码,你就准备好配置Gallery Server Pro来使用你的供应商。将包含在你供应商内部的dll复制到Gallery Server Pro网页应用的bin directory。更新galleryserverpro.config的数据供应商区域。比如,如果你的供应商位于一个名为OracleDataProvider的类中,那一类位于一个名为GalleryServerPro.Data.Oracle.dll 的集合中,数据供应商区域将类似如下:

<dataProvider defaultProvider="OracleDataProvider">

<providers>

<add name="OracleDataProvider" 

type="GalleryServerPro.Data.Oracle.OracleDataProvider, GalleryServerPro.Data.Oracle" />

</providers>

</dataProvider>

图片元数据提取

最长见为JPGs的图片资料能够包括元数据,例如照相机模式以及快门速度。而且,像Vista's Photo Gallery的应用允许用户添加关键词,标题,评级以及更多。Gallery Server Pro能够用下列任何一种形式来截取数据:EXIF, XMP, TEXT, IFD, 以及IPTC。

用以提取元数据的代码基于Code Project文章A library to simplify access to image metadata,其本身又基于Photo Properties。感谢这些作者的辛勤劳动。这些文章中的技术是基于解析能够通过System.Drawing.Image目标的PropertyItems属性的元数据。我refactored其中的大多数代码使其更加易懂(因此能保持更快,更灵活,更健康)。

.NET 3.0中System.Windows.Media.Imaging 名字空间的介绍提供了一种先进的提取元数据的方法,包括获取之前不能输入的资料的能力――特别是标题和关键词。

因此现在有两种方法从图片中获取元数据――.NET 2.0 方式以及 .NET 3.0 方式。即使.NET 3.0技术更优一点,我想让Gallery Server Pro在一个未安装.NET 3.0的系统中工作。

结果,提取元数据运用了以下步骤:

1. 如果.NET 3.0安装在网络服务器中,System.Windows.Media.Imaging namespace??中使用BitmapMetadata类来截取尽可能多的meta数据到一个名为GalleryObjectMetadataItemCollection的custom collection???

2. 将图片Instantiate到 System.Imaging.Image目标。使用PropertyItems属性来截取尽可能多的metadata。对于每个metadata(如切换速度),将其添加到GalleryObjectMetadataItemCollection,但只有当它没有在步骤1中被添加过才可以。

换而言之,使用两种技术来提取同一个元数据,我们就使用.NET 3.0方法而舍弃.NET 2.0方法。

提取元数据数据的逻辑隐藏在业务层类MediaObjectMetadataExtractor中。当图片被添加到相册中时,以下的代码提取于GalleryServerPro.Business.Image构造:

Metadata.MediaObjectMetadataExtractor metadata = new Metadata.MediaObjectMetadataExtractor(imageFile.FullName);

this.MetadataItems.AddRange(metadata.GetGalleryObjectMetadataItemCollection());

变化的imageFile是 System.IO.FileInfo指代图片的例子。MetadataItems属性是GalleryObjectMetadataItemCollection。一旦元数据被提取以及被保存,你可以轻松地遍历项目并获取the name/value pairs:

// Assume we are loading an image with ID=27

IGalleryObject image = GalleryServerPro.Business.Factory.LoadMediaObjectInstance(27);

foreach (IGalleryObjectMetadataItem metadataItem in image.MetadataItems)

{

string name = metadataItem.Description; // e.g. Camera model, Shutter speed

string value = metadataItem.Value; // e.g. F5.7, 1/350 sec

}

总结

这是对用于Gallery Server Pro 的构驾级和编程技术的一个简单介绍。请自便下载源代码,以对您自己的项目有所帮助。

 


本文转自 lu xu 博客园博客,原文链接: http://www.cnblogs.com/dotLive/archive/2007/11/27/974733.html  ,如需转载请自行联系原作者

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
java.net.SocketException: Unexpected end of file from server
java.net.SocketException: Unexpected end of file from server
|
1月前
|
Windows
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
|
9月前
|
SQL 开发框架 前端开发
ASP.NET Core+Element+SQL Server开发校园图书管理系统(完)
ASP.NET Core+Element+SQL Server开发校园图书管理系统(完)
94 0
|
9月前
|
开发框架 JavaScript .NET
ASP.NET Core+Element+SQL Server开发校园图书管理系统(四)(下)
ASP.NET Core+Element+SQL Server开发校园图书管理系统(四)(下)
69 0
|
9月前
|
开发框架 前端开发 JavaScript
ASP.NET Core+Element+SQL Server开发校园图书管理系统(四)(上)
ASP.NET Core+Element+SQL Server开发校园图书管理系统(四)(上)
74 0
|
9月前
|
开发框架 JavaScript .NET
ASP.NET Core+Element+SQL Server开发校园图书管理系统(三)(下)
ASP.NET Core+Element+SQL Server开发校园图书管理系统(三)(下)
52 0
ASP.NET Core+Element+SQL Server开发校园图书管理系统(三)(下)
|
存储 开发框架 关系型数据库
Windows Server 2008 R2配置.Net环境
Windows Server 2008 R2配置.Net环境
199 0
Windows Server 2008 R2配置.Net环境
|
Windows
windows server 2012 R2 .NET Runtime Optimization Service CPU占用高
windows server 2012 R2 .NET Runtime Optimization Service CPU占用高
335 0
|
存储 开发框架 缓存
【浅谈ASP.NET】——视频总结
【浅谈ASP.NET】——视频总结
102 0
【浅谈ASP.NET】——视频总结
|
开发框架 前端开发 JavaScript
ASP.NET MVC+LayUI视频上传
ASP.NET MVC+LayUI视频上传
233 0
ASP.NET MVC+LayUI视频上传