[转载]趋势畅想-搭载android系统的智能数码相机

mikel阅读(1334)

[转载]趋势畅想-搭载android系统的智能数码相机 – SkyD – 斯克迪亚(徐明璐)个人博客 – 博客园.

引言

image虽然当下的智能手机都具备拍照功能,但相比主流卡片数码相机而言,手机的拍照功能都还显得很小儿科,如高速连拍、手动白平衡、1厘米微距、广角等功能都鲜有实现,成像效果与同成像分辨率的卡片机相比也差很多,更不要说与专业级相机相比了。

而另一方面,数码相机虽然硬件强悍,但软件方面仍处于各自为政的混乱局面,各家独立开发自己的系统,而用户也只能默然使用厂家开发的这些功能,想按自己的需求对其进行定制、再开发,是几乎不可能的。

趋势

鉴于Android系统的火爆,很多手机以外的设备也都开始或考虑开始使用这一通用系统。对于数码相机领域而言,Android系统应该是一个足以引发智能革命的契机…

智能相机?有什么不同吗?

image首先它应当搭载一个如Android这样的通用的操作系统,可以使用其中的通用软件,并且由厂商编写出硬件调用API,供开发者开发专用软件。(不是说装了android系统的相机就是智能相机,没有公开具有可编程性的硬件API,再强的系统、镜头或其他硬件也是白搭)

其次其应具备互联网访问能力,这样才能有效地利用android菜市场一类的AppStroe,也可以更便捷地通过网络分享照片或是利用云计算。这方面需要加入wifi或是3G模块。

再有,GPS定位、电子罗盘、重力感应、加速感应等智能手机常见的传感器对智能数码相机也有很大作用,这些是多多益善的,且GPS定位与重力感应在现有数码相机中已经有存在先例了。

此外,蓝牙模块能增进交互效率,并为外接扩展设备提供方便。

简单说:它应当具备现有主流智能手机除了电话、短信功能以外的一切功能。

如果再拥有红外线拍摄功能及红外线补光灯,那就更美妙了。

智能数码相机能做什么不一样的事?

刚买到手的智能数码相机并不能比普通数码相机做更多事情,因为厂商仅仅是将其搭载了android系统,并为之写好了硬件调用API,然后内置了拍照、录像、相册等几个基本程序而已,你需要从菜市场搞来应用,或是基于API开发自己的应用,才能让它变得强大起来。

image使用现有的android应用

你可以在第一时间将现存的各种应用安装到智能数码相机中,以扩展你的相机功能,这些相关应用例如:相册、SNS社区分享、微博、云存储、视频分享、旅行足迹、LOMO效果拍照、拍照面部扭曲恶搞、大头贴、后期照片处理、条码扫描等等。

当然,其他不太相关的应用也可以拿来把玩,比如GPS导航地图、录音机、天气什么的实用程序,或是游戏、装B软件之类的也没问题。

全新开发的专属应用

这才是最激动人心的,也是智能数码相机的存在理由,让我们来设想一下会有什么牛X应用出现吧:

  1. 手持全景拍摄
    通过手持相机,按住快门,以自己为中心转动,使相机形成弧形移动轨迹,在此期间相机会快速连拍,在拍摄后自动合成为全景图。(这种功能在索尼相机中已经实现)
  2. 3D拍摄
    手持相机,按住快门,以拍摄物为中心移动相机为弧形轨迹,拍摄后由程序合成为3D图像格式文件。
  3. 定时自动拍摄
    让相机按时从待机中醒来进行拍摄,拍摄后再恢复待机状态。
    这个应用比较广,例如:
    拍摄某风景在24小时中的变化;
    记录种子萌发过程;
    定时拍摄你的人气小店,并自动发布到网上直播给网友看;
    记录你家庭的每一个温馨的早晨;
    放在镜子前记录你每天的面容变化(减肥效果观测∩_∩);
    定时定点偷拍对面楼美女换衣服(≧▽≦);
    出去玩时把相机挂在脖子上,垂在胸前,然后设定间隔1分钟自动拍摄,然后就尽情的玩吧,回来后整理照片就好;
    如果挂在背后出门,还能观测路人的回头率,芙蓉姐姐必备!
    对于一些特殊行业和岗位,可以要求职员佩戴相机,采用定时+随机拍摄的组合形式,全程记录它们的工作快照,并每日提交给公司,以监督他们是否在工作中有违规或不法行为(例如快递货品检验员、送货员、保安、城管、警察);
    绑在大龄大象身上,结合GPS寻找传说中的大象坟场!
  4. imageHDR拍摄
    关于HDR的说明,可以参看百科:http://baike.baidu.com/view/74850.htm
    简言之,就是通过一张曝光过度的照片和一张曝光不足的照片合成为一个更逼真的照片,合成后的照片保留了高光和暗处的各种细节,所以比常规拍摄出的照片信息更丰富、也更逼真、更具感染力。
    现在HDR的实现方法普遍都是手动拍摄一张曝光不足照片和一张曝光过度照片(有时还需要一张正常曝光的照片),然后再拿到电脑上进行后期合成。其缺陷就是 手动拍摄多次很麻烦,且不用三脚架的情况下,多次取景内容很难完全相同(需要经过 拍摄>审阅>改曝光度>再拍摄 这样多番操作,再拍摄的取景范围肯定有所出入了),还要等到后期合成后才能看到最终效果。
    而通过可编程的智能数码相机,HDR拍摄就是小菜一碟了,只需让程序驱动相机以不同曝光值连拍两张照片,再一合成就搞定了。
  5. 合影闭眼修正
    合影时经常会出现闭眼现象,尤其是人多的情况下,即使拍多张也会出现不是这个闭眼就是那个闭眼的现象。
    让程序来进行简单修正吧,只需长按快门,相机就会快速连拍,拍摄结束后程序会依靠相机的面部识别API自动甄选出没有人闭眼的照片,如果没有的话就进行一下合成互补,输出最终成像。
  6. 模拟景深
    此功能也是索尼卡片相机已经实现的功能,主要就是为了弥补卡片机难以实现背景虚化效果而设计的,原理很简单,就是快速连拍一张正常照片和一张全模糊照片,然后分析焦点,将非焦点部分与模糊照片合成。
  7. 报警器
    利用镜头监视取景(夜间需要红外功能支持),利用麦克风监听环境,一旦有达到一定级别的动静即发出警报,或远程报警并提交成像。(相机:白天拍照,晚上还得盯梢,还让不让活了~杯具)
  8. image远程监视
    类似监控摄像头的功能,但不同的是其可移动性,它将通过网络发送监控图像到控制端。
    这种移动性就带来了更多可能,比如警察、侦探、记者或是怪蜀黍在各种环境盗摄,或者生物学家用于监视动物在巢穴内的活动等。(动物:靠,老子也中木马了!)
  9. 远程对话。通过智能数码相机的镜头、麦克风、喇叭及网络访问功能,实现远程对话是很容易的,这样你就可以把它作为一个远程通话或指挥设备。
  10. 图像内容识别、分析及采集
    通过对取景器中的图像进行分析,获取有用的部分进行处理、存储,以采集所需的信息。
    其应用场景如:
    在路口、收费站等重要位置采集过往车辆的车牌号,将其识别为文本,再将采集时间值一并存入数据库,供警方进行案件调查时快速检索可疑车辆的行驶路径;
    在街道、银行、车站、医院采集行人的面部特征,将其录入数据库,并与通缉犯照片比对,发现类似时及时通知警方;
    在银行柜台前自动记录取款人的面部特征提供给警方使用;
    在某路段上空放置,鸟瞰监测该路段的车流量及拥堵状况或是行人密集度,也可以在监测到重大事故时第一时间报警以启动快速救援,还可用来监测能见度及其他天气状况;
    监测水流速、水位、水色、水质;
    放在汽车上,捕捉并解析路上的各种交通指示牌,显示给司机,避免因没注意看指示牌而走错路、错过高速出口、超速行驶(也可以用来识别路口有没有警察!嘿嘿!);
    回头客检测系统,放在柜台前,对客户面部进行分析,与过往数据进行比对,如果曾经来过本店甚至其他连锁分店,则会向店员提示,并显示过往造访记录甚至是消 费记录,让店员特别注意服务态度(反之也可以用来实现黑名单功能,比如用以在促销活动中杜绝车轮排队者,有这样的功能的话,iPhone4货源就难以被黄 牛党控制了!);
    餐厅满意度统计,扫描并识别顾客的面部表情,统计他们在餐厅中的愉悦程度,用作改善服务效果的参考数据;
    统计街头行人的服装品牌覆盖率;
    抓拍过往行人,自动分析面部特征,以过滤恐龙,只抓拍美女(咩哈哈哈哈,《街头美女宝典》即将出版)。

说到这里,你是不是已经感到所谓的智能数码相机已经不像相机了~,但其实你的智能手机早已不是手机了^^。

而接下来呢,智能数码相机还可以变得更BT一些:

扩展外设

不知道大家有没有使用过索尼的PartyShot智能跟拍底座:

image

介绍视频:http://www.sonystyle.com.cn/products/cyber-shot/partyshot/index.htm

它起初是被用于解决“拍照者总是无法出现在照片中”的遗憾而设计的,它可带动相机进行360°横向旋转,以及一定角度的垂直俯仰,通过相机的面部识 别功能追踪人脸,自动构图,捕捉家庭生活或聚会场景的自然瞬间,这样再不需要某一成员专司拍照,且被拍照者的表情也不会再像以前那样僵硬。

而如果将这类东西的API也提供出来供程序员开发使用,智能相机能做的事情就更多更酷了!

比如上面说过的手持全景拍摄功能,就可以改良为自动全景拍摄,因为手持相机水平移动还是容易出现上下偏移或者抖动等情况,且快速连拍耗电多,还会导 致后期处理耗时长,而交给程序控制自动跟拍底座拍摄就简单多了:把它拧在三脚架上,设置自动全景,它就可以自动每旋转30°拍摄一张照片,然后将拍到的几 张照片完美地组合在一起,拼成全景图。这样360°环状全景图拍摄起来也毫不费力,甚至穹状全景图都能很好地拍出来呢。

而在内容识别时,更可以更好地追踪感兴趣的目标,以获取更清晰的图源和更多信息。

远程监控时,可以由远程控制端调整旋转角度,以避免监控盲区。

另外在交互方面,相机由一块砖型物体变成了可动的玩意,可以进行简单的点头、摇头之类的交互,比如在合影时,如果某人没笑,相机就会摇头以表示不满,是不是也很有意思呢^^

这玩意要是再长两条腿就更好了!你就可以编程让它成为神圣的狗仔队员,追踪拍摄你宝宝的生活瞬间,并自动调整与宝宝的距离,防止被吃掉:)

还有什么顾虑?

以上的愿景应该是大家都希望实现的吧,但是目前貌似还没有哪家厂商开始行动起来,我不认为他们是因没有想到这些才没采取行动,尤其是对一些大厂来说,大多都是有所顾虑才没有开展智能相机的研发吧。

我能想到的最大的阻碍就是成本和能源两个方面:

升格为智能相机,首先就是要推翻现有的所有软件及部分硬件,进行革命性改造,且改换和追加的硬件成本都比较高,仅硬件部分应该就会提升成本千元上 下。但个人感觉,这种程度的增幅,作为消费者我觉得可以接受,比如索尼旗舰卡片机由现在的2000多涨到3000多,而可以拥有那么激动人心的应用,并且 我自己也可以对其进行功能定制开发的话,我觉得还是很值的。

能源问题上,上述应用中很多都需要较大的电量消耗,数码相机厂商应当加速在能源上的研发和改造,才能适应智能相机的需求。我认为在这方面首先就是应 当让相机都支持直流供电,这是最简单最有效的方案,能解决各种定点拍摄应用的用电需求;接着应该考虑采取外接供电装置、双源交替供电、混合能源供电等方 式,让用户可以在户外更容易地补充电量。

突破这两个问题,应该没什么太充分的理由不去研发智能相机、抢占新时代先机了吧。

结语

我相信,通过智能相机的发展,会大幅推动计算机图像识别领域技术的发展,为将来的机器人时代做重要铺垫。

让我们一起来等待见证这令人亢奋的变革吧。

[转载]在最新的Eclipse 3.6 上配置 Java ME 的开发环境! - 勿以善小而为之,勿以恶小而不为 - 博客园

mikel阅读(939)

[转载]在最新的Eclipse 3.6 上配置 Java ME 的开发环境! – 勿以善小而为之,勿以恶小而不为 – 博客园.

首先需要的下载文件有如下:

JDK 1.6\6.0 在SUN公司里直接可以下载到

WTK 2.5.2 手机模拟器,下载地址:http://cds-esd.sun.com/ESD37/JSCDL/sun_java_wireless_toolkit/2.5.2-ml/sun_java_wireless_toolkit-2_5_2-ml-windows.exe?AuthParam=1286288946_7f2743a432fbe7654fae5e86f2d016a9&TicketId=B%2Fw5lh6IT1NMSBdGP1RalgDj&GroupName=CDS&FilePath=/ESD37/JSCDL/sun_java_wireless_toolkit/2.5.2-ml/sun_java_wireless_toolkit-2_5_2-ml-windows.exe&File=sun_java_wireless_toolkit-2_5_2-ml-windows.exe

Eclipse 3.6 下载地址:http://download.actuatechina.com/eclipse/technology/epp/downloads/release/helios/SR1/eclipse-java-helios-SR1-win32.zip

Eclipseme 开发插件下载:http://nchc.dl.sourceforge.net/project/eclipseme/eclipseme/1.7.9/eclipseme.feature_1.7.9_site.zip

在安装依次安装到 Eclipse (这个开源的开发IDE,也是绿色版的,所在在下载解压后能直接打开应用)后,在安装Eclipseme时解压此开发插件,打开Eclipse开发软件, 在点击菜单“help” -》Install New SoftWare,选择“Add”按钮,如图:

在跳出的添加对话框里,点击“Archive…”按钮,按照提示选择当前你解压Eclipseme目录路径,一般都是根目录,里面有SITE.XML安装索引文件,如图操作:

再按“OK”确认后,开始安装步骤,在碰到安装对话框时,基本都是“Next”一路按下去,如果出现提示是否继续安装时,确定继续安装,这样手机的 开发环境基础配置完整了,这次主要说明了Eclipseme的安装与以前的不同,希望准备用Eclipse 3.6 开发手机软件的初学者有所帮助!

[转载]VS 2010 和 .NET 4.0 系列之《ASP.NET 4以及ASP.NET MVC 2中对输出进行HTML编码的新句法》篇

mikel阅读(886)

[转载]VS 2010 和 .NET 4.0 系列之《ASP.NET 4以及ASP.NET MVC 2中对输出进行HTML编码的新句法》篇-Scott Guthrie 博客中文版.

【原文地址】 New <%: %>Syntax for HTML Encoding Output in ASP.NET 4 (and ASP.NET MVC 2)
【原文发表日期】 Tuesday, April 06, 2010 11:57 PM

除了写博客外,我现在还使用Twitter发短贴和共享链接。请通过twitter.com/scottgu跟随我。

这是我针对即将发布的VS 2010 和 .NET 4所撰写的 贴子系列的第十九篇。

今天的贴子讨论ASP.NET 4中引进的一个很小,但非常有用的新句法特性,即能自动到代码片段中对输出进行HTML编码的功能。这有助于保护你的应用和网站免受跨站脚本攻击(XSS)和HTML注入攻击,而且允许你使用一个非常简洁的句法来实现。

HTML编码

跨 站脚本注入(XSS)和HTML编码攻击是网站和应用频受其害的2个最常见的安全问题。它们是在黑客找到方法,把客户端脚本或HTML标识注入网页,然后 这些网页被访问网站的其他访问者浏览时发生的。这可以用来糟蹋一个网站,以及允许黑客运行客户端代码来偷窃cookie数据或者利用用户在网站上的身份做 坏事。

帮助减少跨站脚本攻击的一个方法是确保网页上显示的输出是被HTML编码过了的,这帮助确保任何由终端用户输入或修改过的内容无法在向网页输出时含有象<script> 或 <img>这样的元素。

今天是如何对内容进行HTML编码的

ASP.NET 应用(特别是那些使用ASP.NET MVC的应用)经常依赖使用 <%= %> 代码片段表达式来显示输出。开发人员今天经常在这些表达式内使用Server.HtmlEncode() 或 HttpUtility.Encode()辅助方法在显示输出之前对输出进行HTML编码。这可以用象下面这样的代码来实现:

image

虽然这正常工作,但有2个小缺点:

  1. 有点冗长
  2. 开发人员经常忘了调用Server.HtmlEncode方法,而且没有简单的方法可以对整个应用来核实其用法

新的代码片段句法: <%: %>

在ASP.NET 4中,我们引进了一个新的代码表达式句法,<%:  %>,象<%= %>一样显示输出,但在显示前,会对输出自动进行HTML编码。这免掉了象上面例子那样显式地对内容进行HTML编码的需要,你只要编写象下面这样 更为简洁的代码即可实现完全一样的事:

image

我们选择 <%: %> 句法,是因为很容易快速地替换现有的 <%= %> 代码段实例,它还允许你轻松地在你的代码库查询 <%= %> 元素,发现并核实任何你在应用中没有使用HTML编码的地方,以确保其行为之正确性。

避免双重编码

虽然对内容进行HTML编码通常是个好的最佳实践,但有时你输出的内容就是HTML或者已经编码过了,在这样的情形下,你不想要再做HTML编码。

ASP.NET 4 引进了一个新的 IHtmlString接口 (以及一个具体实现: HtmlString),你可以将其在类型上实现,来表示它的值用来显示HTML时,已经恰当地编码过了(或者已经检查过了),因此它的值不该再作HTML编码了。<%: %>代码片段句法会检查内中代码表达式的值是否实现了IHtmlString 接 口,如果实现了的话,就不再对其输出进行HTML编码。这允许开发人员避免需要每每做决定是用<%= %> 还是用 <%: %>代码片段,而你总可以使用<%: %>代码片段,然后让已经HTML编码过了的任何属性或数据类型实现 IHtmlString接口。

在 <%: %> 中使用ASP.NET MVC HTML辅助方法

举一个这个HTML编码替换机制非常有用的实际例子,考虑一下你在ASP.NET MVC中使用HTML辅助方法的场景。这些辅助方法一般返回HTML。例如,Html.TextBox()辅助方法返回象 <input type=”text”/> 这样的标识。在ASP.NET MVC 2中,这些辅助方法现在默认返回HtmlString类型,表明返回的字符串内容显示是安全的,<%: %>不必再编码了。

这允许你将这些方法在 <%= %> 代码块中:

image

以及 <%: %> 代码块中使用:

image

在上面两种情形中,从辅助方法返回的HTML内容是作为HTML在客户端显示的, <%: %> 会避免做双重编码。

这 允许你在应用中默认使用 <%: %> 代码片段,而不是<%= %>代码块。如果你要是固执(hardcore)的话,你甚至可以创建一个编译规则,在应用中查询 <%= %> 用例,如果发现,将其标记为出错,来强制HTML编码总是发生。

ASP.NET MVC 2 视图的脚手架(Scaffolding)

在 你使用VS 2010 (或者免费的 Visual Web Developer 2010 Express版本)建造ASP.NET MVC 2应用时,你会发现使用“添加视图”对话框生成的视图在输出任何内容时,现在是默认使用 <%: %> 代码块的。例如,下面,我为 Article 对象生成了一个简单的“编辑”视图。注意其中标签,文本框和验证消息的三个 <%: %> 代码片段用例(都是使用HTML辅助方法输出的):

image

结语

新的 <%: %> 句法 提供了一个简洁的方式来自动对内容进行HTML编码,并将其显示为输出。它允许你减少代码的冗长,可以轻松地检查/核实整个网站上的内容都是HTML编码过了的。这可以帮助你的应用免受跨站脚本注入(XSS)和HTML注入攻击。

希望本文对你有所帮助,

Scott

[转载]C#生成CHM文件(中级篇)

mikel阅读(1076)

[转载]C#生成CHM文件(中级篇) – Alexis – 博客园.

在上篇《C#生成CHM文件(入门篇)》中,我们利用微软自带的hhc.exe以编程的方式创建一个CHM文件,而且调用的是一个静态的HMTL文件。

在中篇中,实现以下几个目标
1.将在线的网页保存为CHM文件
2.我们将对我们进行编译的CHM文件进行反编译,使用的还是微软自带的一个exe(hh.exe)。
3.以编程的方式将CHM文件转换为Word

在中篇中,把界面稍微调整了下,如下图

一、将在线的网页保存为CHM文件
曾尝试直接使用网址来编译html文件,结果一直报错,于是就放弃了。现在实现的方法的思想是这样的:先将输入的url地址的网页保存到本地,然后利用 上一篇中的方法生成CHM文件。不过经测试,这样的效率还是比较低的,主要的花费在将htm文件下载到本地,如果带宽不够的话,将会很慢,不过总归是种方 法,大家如果有更好的解决方案,希望能告诉我。

 HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
 HttpWebResponse myResp = (HttpWebResponse)myReq.GetResponse();
 StreamReader respStream = new StreamReader(myResp.GetResponseStream(), Encoding.Default);
 string respStr = respStream.ReadToEnd();
 respStream.Close();
 FileStream fs = new FileStream(startPath+@"\test.htm"FileMode.Create, FileAccess.Write);
 StreamWriter sw = new StreamWriter(fs, Encoding.Default);
 sw.Write(respStr);
 sw.Close();
思路是将网页保存在本地的,startPath为项目所在路径。 大家可以以http://www.baidu.com/index.htm为例(注意要以htm或html为结尾),测试下,看看能不能正常将百度的首页保存到CHM文件中。
效果图是这样的:

二、反编译CHM
反编译CHM的方法同初篇中的利用Process类来进行。

代码

/// <summary>
/// 反编译CHM文件
/// </summary>
/// <param name=”CHMFile”>CHM文件名</param>
/// <returns>返回hhc文件名</returns>
/// <remarks>uses the <see cref=”DecompileChm”></see></remarks>
public string DecompileChm(string CHMFile)
{
string pathDir = Path.GetDirectoryName(CHMFile);//得到chm文件的绝对路径
pathDir = Path.Combine(pathDir, Path.GetFileNameWithoutExtension(CHMFile));
return DecompileChm(CHMFile, ref pathDir);
}
/// <summary>
/// 反编译CHM文件
/// </summary>
/// <param name=”CHMFile”>CHM文件名</param>
/// <param name=”FolderToPut”>反编译后的文件存放路径</param>
/// <returns>返回反编译后的hhc文件名</returns>
/// <remarks>使用hh.exe反编译</remarks>
public string DecompileChm(string CHMFile, ref string FolderToPut)
{
if ((!System.IO.File.Exists(CHMFile)))
{
throw new ArgumentException(CHMFile+文件不存在);
}
if ((!Directory.Exists(FolderToPut)))
{
FolderToPut
= FolderToPut.Replace( , _);
Directory.CreateDirectory(FolderToPut);
}
DirectoryInfo di
= new DirectoryInfo(FolderToPut);
if ((di.Name.Contains( )))
{
throw new ArgumentException(反编译的文件夹名不能包含空格);
}
string strD = null;
strD
= -decompile + di.FullName + + CHMFile;//反编译命令
Console.WriteLine(strD);
Process p
= Process.Start(hh.exe, strD);//调用hh.exe进行反编译

p.WaitForExit();
return Directory.GetFiles(FolderToPut, *.HHC)[0];
}

三、CHM文件转换为Word
接下来,我们来延伸下,利用反编译的文件,将CHM转换成Word文件。思路是这样的:利用反编译,得到hhc文件(hhc文件中包含htm或html文 件的文件名)和一大堆web页面(如果一开始编译进去的是一大堆的话,呵呵),创建一个word文件,将html文件插入到word中,下面以实例的方式 来实现。
为了方便代码管理,我创建了一个类库项目,命名为CHM2Word,里面主要实现将CHM文件反编译并将反编译的文件整合为Word。在CreateCHM项目中调用代码即可,另需要你的机器安装Office2003(对应,添加引用 ->COM->Microsoft Word 11.0 Object Library)或2007(对应,添加引用->COM->Microsoft Word 12.0 Object Library)。

代码

/// <summary>
/// 添加到word中
/// </summary>
/// <param name=”pathFileHHC”></param>
/// <param name=”saveAs”></param>
public void AddToWord(string pathFileHHC, string saveAs)
{
if (File.Exists(saveAs))
{
throw new Exception(word文件已经存在!);
}
Object Nothing
= System.Reflection.Missing.Value;
Microsoft.Office.Interop.Word.Application wApp
= (Microsoft.Office.Interop.Word.Application)this.Word();
Document wDoc
= wApp.Documents.Add(ref Nothing, ref Nothing, ref Nothing, ref Nothing);

if (wApp == null)
{
throw new Exception(转换失败);
}

try
{
string dirfile = “”;//目录位置
dirfile = Path.GetDirectoryName(pathFileHHC);//目录的绝对路径
string[] lines = File.ReadAllLines(pathFileHHC);//读取hhc所有的行,这是为了找出里面的htm或html文件

string quote = “” + (char)34;
long filenumber = 0;

//遍历每一行
foreach (string TextLine in lines)
{
string htmFile = null;

if (TextLine.IndexOf(.html, 0) > 0 || TextLine.IndexOf(.htm, 0) > 0)//如果这一行里面有.htm或者html.的字符串
{

#region 以下代码是获取htm或者html文件名

int endQuote = 0;
if (TextLine.IndexOf(.html, 0) > 0)
{
endQuote
= TextLine.IndexOf(quote, TextLine.IndexOf(.html, 0));
}
else
{
endQuote
= TextLine.IndexOf(quote, TextLine.IndexOf(.htm, 0));
}
int quoteLoop = 0;
quoteLoop
= endQuote 1;
while (TextLine.Substring(quoteLoop, 1) != quote)
{
quoteLoop
= quoteLoop 1;
}
htmFile
= TextLine.Substring(quoteLoop + 1, endQuote quoteLoop 1);//获取html文件的名字

#endregion

htmFile = dirfile + \\ + htmFile;

bool b = false;//是否存在html文件
try
{
b
= File.Exists(htmFile);
}
catch (Exception ex)
{
}
if ((!b))
{
continue;
}
//将文件插入到word中
wApp.Selection.InsertParagraphAfter();
filenumber
+= 1;
if (ProcessFile != null)
{
ProcessFile(
this, new ProcessFileEventArgs(htmFile, filenumber));
}
//InsertFile参数说明
//文件名: 必选的 String. 要被插入的文件名和路径。如果没有指定路径,Word默认为当前文件夹
//Range: 可选的 Object. 如果指定的文件时word, 参数为bookmark(书签). 如果文件为其他类型(如Excel工作表), 参数为指定的一个单元或区域,如 R1C1:R3C4
//确定是否转换 可选 Object.如果值为 True,则 word 应用程序将在插入非“ Word 文档”格式的文档时提示对转换进行确认。.
//链接:  可选 Object. 如果值为 True,则可用 INCLUDETEXT 域插入该文档。
//附件: 可选 Object. 为 True 时将该文件作为附件插入电子邮件消息中。
wApp.Selection.InsertFile(htmFile, ref Nothing, ref Nothing, ref Nothing, ref Nothing);
if ((filenumber % 10 == 0))
wDoc.Save();
}
}
wDoc.Save();
//保存word
wDoc.Close(ref Nothing, ref Nothing, ref Nothing);//关闭
wApp.Quit(ref Nothing, ref Nothing, ref Nothing);//释放

}
catch (Exception ex)
{
}
finally//释放对象
{
if ((wDoc != null))
{
Marshal.ReleaseComObject(wDoc);
wDoc
= null;
}

Marshal.ReleaseComObject(wApp);
wApp = null;
}
}

创建word对象

代码

/// <summary>
/// 创建word对象
/// </summary>
/// <returns></returns>
public object Word()
{
Microsoft.Office.Interop.Word.Application WordApp;
try
{

//WordApp = new Microsoft.Office.Interop.Word.ApplicationClass();//如果是office2003和office2007用这样方法
WordApp = new Microsoft.Office.Interop.Word.Application();//如果是office2010,使用这个方法
}
catch (Exception e)
{
WordApp
= null;
}
return WordApp;
}

反编译导出类主要方法

代码

/// <summary>
/// feedback about processing
/// </summary>
public event EventHandler<ProcessFileEventArgs> ProcessFileIntoWord;//定义一个事件属性
private WordClass withEventsField_w = new WordClass();
/// <summary>
/// 通过这个类,我们可以转换为word,并且把事件传给调用者
/// </summary>
public WordClass w
{
get { return withEventsField_w; }
set
{
if (withEventsField_w != null)//如果不为null,撤销事件
{
withEventsField_w.ProcessFile
-= w_ProcessFile;
}
withEventsField_w
= value;
if (withEventsField_w != null)//如果不为null,注册
{
withEventsField_w.ProcessFile
+= w_ProcessFile;
}
}
}
/// <summary>
/// 主要函数:反编译、导出
/// </summary>
/// <param name=”ChmFile”>待反编译的CHM文件</param>
/// <param name=”DocFile”>word文件名</param>
/// <remarks>word文件一定不存在</remarks>
public void DecompileAndExport(string ChmFile, string DocFile)
{
try
{
Decompile d
= new Decompile();//实例化一个反编译类
string strHHC = d.DecompileChm(ChmFile);//获取hhc文件
w.AddToWord(strHHC, DocFile);//调用word类的添加到word中方法
}
catch (System.Runtime.InteropServices.COMException ex)
{
//throw new clsError(“Com exception:” + ex.Message, ErrorsOcurred.ComError);
}

}

我利用刚刚生成的baidu的CHM导出的word如图:

效果还是不错的,呵呵。如果你的CHM文件大的话,导出的时间可能会比较长一些。

PS:
1.如果你使用的是office2003或者office2007,需要修改类库项目下的WordClass类下Word方法,因为office2010的
Microsoft.Office.Interop.Word.ApplicationClass不再提供构造方法,而是提供Microsoft.Office.Interop.Word.Application()接口
2.如果在转换的工程中,始终没有反应,可以调试下,如果出现这样的错误,“因为没有打开的文档,所以这一命令无效”。

调试中不会弹出异常,但是将鼠标放到wApp对象中,查看的会发现那样的错误,原因是因为权限不够,可以采用如下方法解决:

运行dcomcnfg打开组件服务,依次展开”组件服务”->”计算机”->”我的电脑”->”DCOM配置”

找到”Microsoft Word应用程序”,右键打开属性对话框,
点击”标识”选项卡,点击”标识”标签,选择”交互式用户”(此设置可能对计算机安全存在威胁,如不设置可以解决问题就不设置,点”下列用户”,把管理员的用户administrator密码….正确填写进去也行)
点击”安全”选项卡,依次把”启动和激活权限”,”访问权限”,”配置权限”,都选择为自定义,然后依次点击它们的编辑,把everyone添加进去,并加入所有的权限…
OK,解决此问题!
如果你的office是2010或者你的系统版本较高的话,很有可能遇到这样的问题。我的电脑是windows7+office2010,就遇到了这样的问题。

3.在反编译和在线生成CHM的时候会生成一些临时文件,如果不及时删掉的话,会造成空间的浪费。我们自己可以写一个简单的删除程序,这个应该很简单,如果不会的,可以参考我以前项目中的代码,http://www.cnblogs.com/alexis/archive/2010/07/03/1770409.html

在下篇(应用篇)中,我将说说如何将这些技术运用到实际中。

[转载]PowerDesigner15官方正式版+注册补丁

mikel阅读(1032)

[转载]PowerDesigner15官方正式版+注册补丁,Java技术文章,Java系列教程,Java.

PowerDesigner15官方正式版+注册补丁

www.firnow.com    时间 : 2009-09-08  作者:匿名   编辑:小张 点击:  2302 [ 评论 ]

(1)软件介绍:
PowerDesigner是Sybase公司的CASE工具集,使用它可以方便地对管理信息系统进行分析设计,它几乎包括了数据库模型设计的全过程。利 用PowerDesigner可以制作数据流程图、概念数据模型、物理数据模型,可以生成多种客户端开发工具的应用程序,还可为数据仓库制作结构模型,也 能对团队设计模型进行控制。它可与许多流行的数据库设计软件,例如:PowerBuilder,Delphi,VB等相配合使用来缩短开发时间和使系统设 计更优化。

(2)官方下载:
目前 PowerDesigner 最新官方正式版本为 15.1.0.2850 ,謾軻提供官方下载地址:
主程序:PowerDesigner15_Evaluation.exe
http://download.sybase.com/eval/PowerDesigner/PowerDesigner15_Evaluation.exe
类库: PowerDesigner15_Library.zip
http://download.sybase.com/eval/PowerDesigner/PowerDesigner15_Library.zip
(2)注册(破解)方法:
1.点击以上链接到官方下载 PowerDesigner 15.1.0.2850 最新正式版并安装;
2.下载謾軻提供的注册补丁 pdflm15.dll [点击下载],然后替换原安装目录里的 pdflm15.dll 文件;
3.重启 PowerDesigner 15 即完成破解。

(3)破解说明:
对于 PowerDesigner15 的破解,网上盛传的方法是通过 pdflm15.dll + license.lic 破解补丁进行破解,然而謾軻亲自试验后发现这种方法其实只适用于 PowerDesigner12 的破解,用在 PowerDesigner15 身上则会出现如下错误提示:

diyblPic

错误提示1: PowerDesigner:pdshell15.exe-无法找到入口

无法定位程序输入点?SExceptionDialog_@@YAHPBDOJPB_WZZ于动态链接库PDCore15.dll上。

diyblPic

错误提示2: Sybase PowerDesigner(R)

Cannot load license management library(pdflm15)

针对这种现象,謾軻通过对 PowerDesigner15 的研究发现,官方加强了程序的保护措施,在动态链接库 PDCore15.dll 做了手脚,于是謾軻花了将近2个多小时的睡眠时间终于把 PowerDesigner15 破解出来,而且在只修改官方 pdflm15.dll 一个文件的情况下完成了注册效果,保持了软件原有的稳定性,废话少说,謾軻以图为证,希望对大家有所帮助:

diyblPic

官方原版为15天试用版

diyblPic

破解后为企业正式版

[转载]SQL Server 2008批量删除数据表

mikel阅读(1368)

[转载]SQL Server 2008批量删除数据表_飞宏风_百度空间.

测试数据
create table dbo.temptb_1 (id
int);
create table guest.temptb_2 (id
int);

打开隐式事务
SET IMPLICIT_TRANSACTIONS ON
执行动态删除
–定义一个变量

declare @SQL varchar(max);
set @SQL=;
select @SQL=@sql+drop table +
–获取表名称,形如:dbo.temptb_***,escape ‘\’表示’\’为转义符号
QUOTENAME(SCHEMA_NAME([schema_id]))
+.+QUOTENAME([name])+;
from sys.tables where where is_ms_shipped =0 and [name] like temptb\_% escape \’
— select @sql;
EXEC(@sql);
检查删除是否正确
select * from sys.tables
正确,则提交事务,确认删除
commit tran
不正确,则回滚事务,取消删除
rollback tran
关闭隐式事务
SET IMPLICIT_TRANSACTIONS OFF

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)

mikel阅读(1003)

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1) – Taven – 博客园.

本文将开始一步一步地使用ASP.NET MVC 2 + Castle + NHibernate 开发一个项目。

在开始之前,我先对这三个组件做一个简单的介绍:

ASP.NET MVC

它是微软提供的一个基于MVC标准的Web开发模式,其典型特点是有控制器和视图;在这之前,.NET下的Web开发模式大多是采用WebForm,其典型特点是服务端控件和后台触发事件;

NHibernate

它是一个ORM框架,使用Java的SSH做过项目开发的人就非常熟悉了,当前最新版本为NHibernate 3.0,听说完全支持Linq查询语句了,以前只支持HQL语句。

Castle

它是一个非常大的框架,包含IoC、MVC、ORM、AOP等,这次我只用到其IoC的功能。

关于IoC

IoC的英文是Inversion of Control,中文意思是控制反转,也有称其为Dependence Injection,中文意思是依赖注入,也就是DI;

除了Castle可以作IoC 外,还有著名的Spring.Net、Unity等,在我另外一个开源博客项目 http://rorowo.codeplex.com/ 中就用到了微软的Unity 2.0作为IoC。

好了,废话不多说,下面开始。

首先,第一步是创建一个解决方案,项目结构如下:

需要引用的DLL库文件,我们全部放在RoRoWo.Common.DependLib下:

根据表的结构,如图:

现在我们开始为表结构创建实体类,以BlogCategory表为例,我们根据该表的字段名称和数据类型创建一个POCO类,放在RoRoWo.Domain.Entities下,代码内容如下:

代码

namespace RoRoWo.Domain {

public class Blogcategory {
public Blogcategory() { }
public virtual int Cateid { get; set; }
public virtual IList<Blogarticle> Blogarticles { get; set; }
public virtual string Catename { get; set; }
public virtual int Parentid { get; set; }
public virtual int State { get; set; }
public virtual int Sortid { get; set; }
public virtual int Articlecount { get; set; }
public virtual System.DateTime Createtime { get; set; }
public virtual string Note { get; set; }
}
}

在这里,我推荐一个可以生成NHibernate映射对象代码的工具(开源的),项目地址:NHibernate Mapping Generator(它同时支持 hbm.xml文件的方式、Fluent Mapping方式、Castle ActiveRecord方式)

接下来,要为这个类创建一个映射关系,我这里使用配置文件的方式,但是正式项目推荐使用Fluent方式。我们创建一个XML文件,文件名为“Blogcategory.hbm.xml”,放在RoRoWo.Domain.Mappings下,内容如下:

代码

<?xml version=1.0 encoding=utf-8?>
<hibernatemapping assembly=RoRoWo.Domain namespace=RoRoWo.Domain xmlns=urn:nhibernate-mapping-2.2 defaultlazy=false>
<class name=Blogcategory table=BlogCategory>
<id name=Cateid column=CateID>
<generator class=native />
</id>
<property name=Catename column=CateName />
<property name=Parentid column=ParentID />
<property name=State column=State />
<property name=Sortid column=SortID />
<property name=Articlecount column=ArticleCount />
<property name=Createtime column=CreateTime />
<property name=Note column=Note />
</class>
</hibernatemapping>

这里就是一个典型的映射关系了,如果有一对多,多对多的表关系,也是在这个配置中进行维护。

创建这个XML后,还有个很重要的操作,就是将其设为“嵌入的资源” ,鼠标右键查看“Blogcategory.hbm.xml”文件属性,将“生成操作”项的“内容”改为“嵌入的资源”,如图:

到此,一个映射关系的实体就建立好了,下面我们就要来实现NHibernate对该表的增删改查操作了,我们把这些操作的实现放在RoRoWo.Data中。

注意,RoRoWo.Data需要添加对 “Castle.Core.dll” Castle.DynamicProxy2.dll NHibernate.dll RoRoWo.Domain 的引用。

在创建数据库操作类之前,我们需要创建一个 “SessionManager”类,它负责维护整个ORM中的上下文,这里我使用李永京的一个类,其代码如下:

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NHibernate;
using NHibernate.Cfg;

namespace RoRoWo.Data
{
public class SessionManager
{
private ISessionFactory _sessionFactory;
public SessionManager()
{
_sessionFactory = GetSessionFactory();
}
private ISessionFactory GetSessionFactory()
{
return (new Configuration()).Configure().BuildSessionFactory();
}
public ISession GetSession()
{
return _sessionFactory.OpenSession();
}
}
}

我们创建一个“BlogCategoryRespository.cs”文件,其代码如下:

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;
using RoRoWo.Domain;

namespace RoRoWo.Data
{
public class BlogCategoryRespository
{
private ISession _session;
public ISession Session
{
set
{
_session = value;
}
}

public BlogCategoryRespository(ISession session)
{
_session = session;
}

public Blogcategory GetById(int cateId)
{

return _session.Get<Blogcategory>(cateId);
}

public void Create(Blogcategory dto)
{
_session.Save(dto);
_session.Flush();
}

public int CreateAndReturn(Blogcategory dto)
{
int newid = (int)_session.Save(dto);
_session.Flush();
return newid;
}

/// <summary>
/// 使用事务
/// </summary>
/// <param name=”dto”></param>
/// <returns></returns>
public int CreateTransaction(Blogcategory dto)
{
using (ITransaction tx = _session.BeginTransaction())
{
try
{
int newId = (int)_session.Save(dto);
_session.Flush();
tx.Commit();
return newId;
}
catch (HibernateException)
{
tx.Rollback();
throw;
}
}
}

public void UpdateCustomer(Blogcategory dto)
{
_session.Update(dto);
_session.Flush();
}

public void SaveOrUpdate(IList<Blogcategory> dtos)
{
foreach (var c in dtos)
{
_session.SaveOrUpdate(c);
}
_session.Flush();
}

public void Delete(Blogcategory dto)
{
_session.Delete(dto);
_session.Flush();
}

public IList<Blogcategory> From()
{
//返回所有Blogcategory类的实例
return _session.CreateQuery(from Blogcategory)
.List<Blogcategory>();
}

public IList<int> Select()
{
//返回所有Blogcategory的CateId
return _session.CreateQuery(select c.CateId from Blogcategory c)
.List<int>();
}

public IList<Blogcategory> Where()
{
return _session.CreateQuery(from Blogcategory c where c.CateId=’3′)
.List<Blogcategory>();
}

public IList<Blogcategory> GetGreaterThan(int CateId)
{
//return _session.CreateQuery(“select from Blogcategory c where c.CateId > :cid”)
// .SetInt32(“cid”, CateId)
// .List<Blogcategory>();

return _session.CreateCriteria(typeof(Blogcategory))
.Add(Restrictions.Gt(CateId, CateId))
.List<Blogcategory>();

}

public IList<Blogcategory> CreateCriteria()
{
ICriteria crit = _session.CreateCriteria(typeof(Blogcategory));
crit.SetMaxResults(50);
IList<Blogcategory> blogcategorys = crit.List<Blogcategory>();
return blogcategorys;
}

public IList<Blogcategory> Narrowing()
{
IList<Blogcategory> blogcategorys = _session.CreateCriteria(typeof(Blogcategory))
.Add(Restrictions.Like(Catename, s%))
.Add(Restrictions.Between(Parentid, 1, 3))
.List<Blogcategory>();
return blogcategorys;
}

public IList<Blogcategory> Query()
{
Blogcategory dtoSample = new Blogcategory() { Catename = sss, Parentid = 0 };
return _session.CreateCriteria(typeof(Blogcategory))
.Add(Example.Create(dtoSample))
.List<Blogcategory>();
}

public IList<Blogcategory> UseQueryByExample_Get(Blogcategory dtoSample)
{
Example example = Example.Create(dtoSample)
.IgnoreCase()
.EnableLike()
.SetEscapeCharacter(&);
return _session.CreateCriteria(typeof(Blogcategory))
.Add(example)
.List<Blogcategory>();
}

}
}

该代码具有了对一个表的基本操作,现在我们就来创建一个单元测试,测试一下插入数据。

在创建插入操作时,我们要能使NHibernate正常工作,还需要创建一个配置文件,我们创建一个XML文件,文件名为“hibernate.cfg.xml”,放在RoRoWo.UnitTest下,其内容为:

代码

<?xml version=”1.0″ encoding=”utf-8″?>
<hibernate-configuration xmlns=”urn:nhibernate-configuration-2.2″ >
<session-factory>
<property name=”connection.driver_class”>NHibernate.Driver.SQLClientDriver</property>
<property name=”connection.connection_string”>
Data Source=.;Initial Catalog=RoRoWoDB;User ID=sa;Password=2010;
</property>
<property name=”adonet.batch_size”>10</property>
<property name=”show_SQL>true</property>
<property name=”dialect”>NHibernate.Dialect.MsSQL2005Dialect</property>
<property name=”use_outer_join”>true</property>
<property name=”command_timeout”>10</property>
<property name=”query.substitutions”>true 1, false 0, yes ‘Y’, no ‘N’</property>
<property name=”proxyfactory.factory_class”>
NHibernate.ByteCode.Castle.ProxyFactoryFactory,
NHibernate.ByteCode.Castle
</property>
<mapping assembly=”RoRoWo.Domain”/>
</session-factory>
</hibernate-configuration>

其中“Data Source=.;Initial Catalog=RoRoWoDB;User ID=sa;Password=2010;”是我的数据库连接,您可以改为您的。

现在我们添加一个单元测试(不明白如何添加的请参考相关资料),先测试插入方法,其代码如下:

代码

/// <summary>
///Create 的测试
///</summary>
[TestMethod()]
public void CreateTest()
{
SessionManager sessionManager = new SessionManager();
ISession session = sessionManager.GetSession();
BlogCategoryRespository target = new BlogCategoryRespository(session);
Blogcategory dto = new Blogcategory();

dto.Catename = 新分类 + new Random().Next(100000, 999999).ToString();
dto.Parentid = 0;
dto.State = 0;
dto.Createtime = DateTime.Now;

int newid = target.CreateAndReturn(dto);
Assert.IsTrue(newid > 0);
}

执行单元测试,可以通过测试,并且在数据库中已经成功插入了一条记录,结果完全正确;

我们接着对查询方法进行测试,我们将测试代码如下:

代码

/// <summary>
///GetById 的测试
///</summary>
[TestMethod()]
public void GetByIdTest()
{
SessionManager sessionManager = new SessionManager();
ISession session = sessionManager.GetSession();
BlogCategoryRespository target = new BlogCategoryRespository(session);
int cateId = 3;
Blogcategory actual;
actual = target.GetById(cateId);
Assert.AreEqual(cateId, actual.Cateid);

}

/// <summary>
///From 的测试
///</summary>
[TestMethod()]
public void FromTest()
{
SessionManager sessionManager = new SessionManager();
ISession session = sessionManager.GetSession();
BlogCategoryRespository target = new BlogCategoryRespository(session);
IList<Blogcategory> actual;
actual = target.From();
Assert.IsTrue(actual.Count > 0);

}

/// <summary>
///Select 的测试
///</summary>
[TestMethod()]
public void SelectTest()
{
SessionManager sessionManager = new SessionManager();
ISession session = sessionManager.GetSession();
BlogCategoryRespository target = new BlogCategoryRespository(session);
IList<int> actual;
actual = target.Select();
Assert.IsTrue(actual.Count > 0);
}

/// <summary>
///Where 的测试
///</summary>
[TestMethod()]
public void WhereTest()
{
SessionManager sessionManager = new SessionManager();
ISession session = sessionManager.GetSession();
BlogCategoryRespository target = new BlogCategoryRespository(session);

IList<Blogcategory> actual;
actual = target.Where();
Assert.IsTrue(actual.Count > 0);
}

/// <summary>
///GetGreaterThan 的测试
///</summary>
[TestMethod()]
public void GetGreaterThanTest()
{
SessionManager sessionManager = new SessionManager();
ISession session = sessionManager.GetSession();
BlogCategoryRespository target = new BlogCategoryRespository(session);
int CateId = 0; // TODO: 初始化为适当的值
IList<Blogcategory> actual;
actual = target.GetGreaterThan(CateId);
Assert.IsTrue(actual.Count > 0);

}

测试结果全部绿灯通过:

下一篇,我将谈谈如何配置一对多和多对多的表映射关系。

该例子的完整代码可以到开源平台下载,地址: http://rorowoproject.codeplex.com

文章中如有不足之处,望大家多指正

[转载]前端管窥:图片Sprite管理

mikel阅读(972)

[转载]前端管窥:图片Sprite管理 – BENNY CHIA! – 博客园.


Sprite 是每个前端工程师处理图片的基本技能。有些工程师昵称这项技能为“雪碧”,可见大家对这个东西的关爱程度。所谓图片的sprite技术,就是把网站用到的 小图片整合在一张比较大的“地图”上,然后在页面容器里对这张“地图”采用背景图片定位的方式来调用此处需要用到的那张小图片的位置。
Sprite的优势:
使用图片sprite技术的优势有三:一,减少针对图片的http请求 数,如果使用许多小图片的方式来组织页面,势必会造成加载页面的时候对每个图片文件形成一个http请求,如果使用sprite技术,则页面只需要对这些 小图片组成的大图进行一次请求即可,减小了网络负担。二,减小图片大小。使用sprite生成的大图其文件大小比其组成部分的小图片大小的总和要小,图片 越小,下载越快。且图片下载后所有在大图上的图片同时刷新出来,而不是每个图片分别刷新,网页的视觉整体性要好。三,便于图片管理。网页需要的各种尺寸的 icon图标和按钮图片等以整齐的顺序排列,便于图片修改和管理。
Sprite的劣势:
sprite的好处就是上面那些,不好之处也是有的,比如,如果你需要一 张背景透明的图片,众所周知IE6对png图片的支持不好,处理img图片尚有解决方法,处理背景平铺也有对策,但是处理一个sprite定位的背景图片 现在还没有好的解决方案。有些方案虽然能解决,但是对客户端造成的负担可以让你得不偿失。
这让我想到table和div之间的争论,有人做页面重 构工作,将一切table均使用div代替,事实是显示数据的表格还是table效果最好,非但数据表格,有些页面布局能够使用table简单解决,就不 必把问题复杂化。facebook和人人的弹窗就是用table写的,效果很好。
一些经验和建议:
现在在工作中,sprite图片越来越大,有的项目中sprite图片居然超 过1000px,这时我们就得去看看,这些组成sprite的小图片组织得是否合理。举例来看,google的logo图片下方充满了小图标,整个 google搜索页只用了这么一张28k大小的图片:

这么做对于google这种sprite基本不变,同时十分重视每1k图片大小的优化的网站来说,这么做有他的道理。但是在一般网站来说,我不建议 采用google的sprite排列方式,尤其不建议把logo做到sprite里。出于经常维护的需要,我们需要更好的图片维护,sprite最好能够 有一种规则,让你对其中每一个图标的位置都清清楚楚。

比如,利用PS的网格工具做参考,或者在PSD文件中建立一个框架图层,将网站各种尺寸的图标放在不同的横行,每个图标之间留出同样的尺寸,如果是 16px的icon,可以在每个16px的空间右边空出5px的距离放下一个图标,这样的话两个图标左边缘的距离就是21px,如果sprite左边第一 个icon的background-position为0 0的话,第10个icon的background-position就是-210px 0。这样你可以精确地知道每个图标的位置,今后调用图标只需要心算一下即可。


如果sprite图片的第一行放了16px的icon,第二行就可以用来安放24px的icon。如果sprite图片的宽度过大,也会对图片管理形成不便,这时候就可以把头一行的icon换行,放在24px的icon下方即可。
工作中还会碰到一种情况,做好的sprite图,优化得不是很好,出现了大的空隙,同时还有好多小图标放的地方不合适,想把这些图标移到空 隙里面去,这种工作岂不是要一个一个计算图标位置,麻烦可大了。我在这里给大家介绍个经验,开着css文件的同时开着excel,可以给你很大帮助。

如图,icon图标已经按照上面说的方法每21px安放一个,每个的位置我都很清楚,第一个图标的定位是-735px 0,第二个图标的定位是-756px 0。需要移动的图标在同一横行,图标数是23个。然后我把需要调整的icon整行剪切到图中另外一个位置,记下第一个图标在新位置的定位-63px -242px,第二个图标在新位置的定位是-84px -242px。于是把这两组数按图写进excel表里,并向下拉出共23行的等差数列,23个图标新旧位置的对应关系便出来了。然后在css中查找原来的 值并替换新值即可。如果找不到原来的值,说不定是原来在工作中为了处理特殊效果改变了正常的定位,后面做出“无”标记,单独处理就可以了。
总结
所以说,写好一个sprite对今后维护是多么重要的事情呵。下课~

[转载]11个IT人士必备的Chrome 插件

mikel阅读(1305)

[转载]11个IT人士必备的Chrome 插件 – Memento.. – 博客园.

Chrome 浏览器现在可谓如日中天,与 Firefox 共同蚕食着 IE 的市场,网页开发者们可能也会开始转向这一新兴的浏览器,来调校自己的网站。而随着 Chrome 插件作者们的介入,为网页开发者提供便利的插件也纷纷崭露头角。

1. Firebug Lite

firebuglite

Firebug 绝对是最受网页开发者喜爱的 Fifefox 插件(没有之一)。通过它可以在浏览器中查看并编辑任何网页的 HTML,CSS 以及 JavaScript,并在修改的同时地看到改动后的效果。Firebug Lite 是针对 Chrome 浏览器的一个精简版本,可以用来查找网页中的错误以便快速更正。

尽管 Firebug Lite 尚不能包括 Firebug 所有功能,但也已经秉承其精粹,且已经提供了针对高级用户控制台界面。

2. IE Tab

ietab

微软的 Internet Explorer 浏览器会让很多网页设计者头痛,但目前为止在大众范围内仍是被使用最多的浏览器。IE Tab 扩展实际上是在 Chrome 的一个标签页里用 IE 打开网页,通过它你可以查看网页在 IE 用户的眼里是否显示正常。

3. Eye Dropper

eyedropper

通 过 EyeDropper,可以查看 Chrome 浏览的网页中任意颜色的信息。点击扩展的按钮,会打开一个下拉式的色轮界面,其中有一个取色器按钮(Pick color from webpage),点击它,再点击网页中任何位置,就可以查看所点击位置像素的颜色在色轮中的位置、RGB 水平以及 HTML 颜色代码。

4. Chrome SEO

measureit

安装好该插件后点击插件按钮就会显示当前网站与搜索引擎优化相关的信息,包括反向链接,Alexa排名、Google PageRank排名等流量值数,在社会化书签网站中的热门程度等。

5. Lorem Ipsum Generator

loremipsum

Lorem Ipsum Generator 扩展可以用来在设计网页时生成填充网页内容的文本,用以调适格式,免去手动输入此类文字浪费的时间。该插件十分小巧,在易于使用的同时也不会占用过多的内存,在需要时可以信手拈来。

6. Resolution Test

resolutiontest

顾名思义,Resolution Test 就是通过调整浏览器的大小来查看网站在不同的常见分辨率下的情况。作为网页设计者一般都会配备高分辨率的显示器,但一般的网页访问者来说通常都不会这么奢侈,这个扩展的作用就是用来确保网站的格式在这部分人看来也是正常的。

7. Speed Tracer

speedtracer

Speed Tracer 通过浏览器内建的测量工具来记录网页应用在执行不同任务时所用的时间,以便于开发者找到致使网站运行缓慢的原因。该插件可以显示浏览器在解读执行布局、JavaScript时所有的时间以及其它一些细节。

这个插件唯一的缺点在于,必须使用“–enable-extension-timeline-api”这个参数来启动 Chrome 浏览器才能让其正常运作。但既然是网站开发者,这点麻烦就是小菜一碟了,对吧?

8. MeasureIt!

measureit

MeasureIt! 名字就很直观。它可以显示出所浏览网页中任意元素的尺寸(像素宽度和高度)。和这个列表中很多插件一样,这个插件也有 Firefox 版本。

9. 1-Click Web Proxy

地址: https://chrome.google.com/extensions/detail/kjdehhkgdgjcekacdccoflccmhbkefce

这个插件应该是国人做的。因为她的中文名字是——  一键翻墙!

她已经连续一个月排到Chrome Extension 官方Top Rated的第7名了~ 囧~ 看来还真是迎合国民的需求啊~

真相在这里:https://chrome.google.com/extensions/list/rating

做IT的经常去国外网站查资料,遇到打不开的网页,比如google groups 、blogspot等,只需要点击这个插件的按钮就可以了。速度还挺不错。

10. Pendule

pendule

Pendule 会弹出一个简单易用且设计精美的控制面板,其中包含了很多对于开发者来说很有帮助的任务选项。比如重新载入或是禁用 CSS,查看 JavaScript 代码,隐藏图片,取色器,测量尺,查看页面源代码,以及多种编码验证工具等。是一个很不错的功能基础且全面的开发者用扩展。

11. BuiltWith

builtwith

BuiltWith 可以给出关于当前网页的一个资料信息,列出了网站中所使用的相关技术。它会显示网页中所使用的小挂件、网站管理员所用的网站流量分析追踪服务、网页所使用的框架以及广告平台等等。

[转载]C#生成CHM文件(入门篇)

mikel阅读(1237)

[转载]C#生成CHM文件(入门篇) – Alexis – 博客园.

HTML Help Workshop介绍:微软出品的HTML Help WorkShop制作chm文件的最佳工具。

本文,我们将用编程的方法来实现将html文件编译成CHM文件。在开始编程之前,我们有必要了解下HTML Help Workshop是怎么生成CHM的。

HTML Help Workshop编译成CHM文件需要如下三个文件,分别以hhp,hhc,hhk为文件后缀名。

hhp:CHM工程文件,CHM目标文件属性95%的参数都在这里被确定.
hhc,列表文件,确定目标文件中左侧树形列表中”目录”选项卡下的内容.
hhk,索引文件,确定目标文件中左侧树形列表中”索引”选项卡下的内容.
hhp几乎就是一个标准的ini文件.分为三个小节Option,Windows,Files.

典型的配置文件(hhp)结构如下:

[OPTIONS]
Compatibility=1.1 Or later
Default window=Main
Default font=宋体,9,1
Contents file=test.hhc
Index file=test.hhk
Display compile progress=Yes
Full-text search=Yes
Language=0X804 中文(中国)

[WINDOWS]
Main=,”test.hhc”,”test.hhk”,,,,,,,0x20,0xB4,0x104E,[80,60,720,540],0x0,0x0,,,,,0

[FILES]
NewTopic.html

稍微解释下:

Default window=Main:默认的显示模式,这里是主页面

Default font=宋体,9,1:默认的字体

Contents file=test.hhc:内容文件

Index file=test.hhk:索引文件

Display compile progress=Yes:是否显示编译过程

Full-text search=Yes:是否全文搜索

Language=0X804 中文(中国):默认语言

索引文件(hhk)也是一个HTML文件,它包含若干个关键词,当用户打开chm文件后,单击索引标签并输入一个关键词后,chm文件将显示与这个关键词有关的主题的列表,使大家非常方便地找到相关主题。 典型的文件结构如下:

代码
DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <HTML> <HEAD> <meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1">   HEAD> <BODY> <UL>  <LI> <OBJECT type="text/sitemap">  <param name="Name" value="NewTopic">  <param name="Local" value="NewTopic.html">  OBJECT> UL> BODY> HTML>
 
内容页项目资源hhc)文件结构如下:
代码
DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <HTML> <HEAD> <meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1"> HEAD> <BODY> <OBJECT type="text/site properties">  <param name="Window Styles" value="0x237"> OBJECT> <UL>  <LI> <OBJECT type="text/sitemap">  <param name="Name" value="NewTopic">  OBJECT> <UL>  <LI> <OBJECT type="text/sitemap">  <param name="Name" value="NewTopic">  <param name="Local" value="NewTopic.html">  OBJECT> UL> UL> BODY> HTML>
 

用C#编程实现编译,其实是利用Process类来调用exe实现的。
代码
Process helpCompileProcess = new Process(); //创建新的进程,用Process启动HHC.EXE来Compile一个CHM文件  try  {  //判断文件是否存在并不被占用  try  {  string path = _chmFile; //chm生成路径  if (File.Exists(path))  {  File.Delete(path);  }  }  catch  {  throw new Exception("文件被打开!");  }  ProcessStartInfo processStartInfo = new ProcessStartInfo();  processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;  processStartInfo.FileName = hhcFile; //调入HHC.EXE文件  processStartInfo.Arguments = "\"" + Path.GetFullPath(GetPathToProjectFile()) + "\"";//获取空的HHP文件  processStartInfo.UseShellExecute = false;  helpCompileProcess.StartInfo = processStartInfo;  helpCompileProcess.Start();  helpCompileProcess.WaitForExit(); //组件无限期地等待关联进程退出  if (helpCompileProcess.ExitCode == 0)  {  MessageBox.Show(new Exception().Message);  return false;  }  }  finally  {  helpCompileProcess.Close();  }  return true;
 

附件是项目,.Net4.0的,有兴趣的可以在其他版本上也实现下,只要将文件拷过去即可。

如果是vs2010,直接运行项目即可,在运行项目之前可以先把CreateChm\bin\Debug目录下的hhp、hhc、hhk、chm文件全部删掉,运行程序后后生成这些文件。

PS:我尝试将一些引用js文件和图片的html文件,将他们编译为chm文件时,这些js文件和图片能够自动被包含到chm文件中,呵呵,这样就可以创建丰富多彩的chm文件了,如我给的demo中,指针就是一个漂亮的时钟,关于更复杂的CHM编程,稍后带来。

PS:如果觉得的好的话,请点推荐,如果值得收藏的话,请点收藏,3Q

C#创建简易CHM文件Demo