基于
Web
的图像编辑实现方案(上)
Web应用是飞速发展的网络时代的主角,软件的Web化不仅仅是使得可移动性变得更强,更重要的是增加了用户之间更深入的协作和交互的可能性。应用的操作可以发生在本机或网络上。在Web上目前实现的应用很多,特别是Google推出的Web软件产品比较引人注目,甚至Adobe首席执行官布鲁斯在3月份就宣称要推出可托管的在线PhotoShop版本!
那么如何在Web实现比较流畅的图像编辑,实现的方案有很多,但是基本可以分为两大类:插件方式、非插件方式。插件方式实现的方法比较常见,例如采用Flash插件或Java Applet或其它自行开发的图形处理插件等,甚至包括微软目前正在大力推广可以与Flash挑战的新兴技术SilverLight技术。目前比较成熟的是Flash方式,也有很多的涂鸦网站正在使用该技术,而几乎可以和PhotoShop相提并论的fauxto、fototool等更是登峰造极之作。非插件的方式目前还比较少,有些是纯粹基于客户端静态脚本来
实现的,所编辑的图像只是一种伪图像,例如可能是很多点的集合,比较高级的发展到用动态语言来实现,例如用
ASP
、
PHP
等,这种技术目前也比较成熟(例如基于
GD
或
I
mageMagick
等
),国内也有类似的网站实现了ASP版的图像在线处理。那么在发展到.Net时代后有没有更好的解决方案呢?下面我们先来比较下上面提到的几种方案。
功能
|
插件
|
静态非插件
|
动态非插件(无.Net
)
|
需要下载
/安装插件
|
需要
|
不需要
|
不需要
|
支持多种图像格式
|
不方便
|
不支持
|
可以支持
|
支持文字输入/特效字体
|
不方便
|
可以支持
|
可以支持
|
支持图像特效滤镜处理
|
不方便
|
可以支持
|
可以支持
|
数据库、网络等外部图像加载
|
不方便
|
不支持
|
不方便
|
图像处理历史记录保存/回放
|
很好
|
不支持
|
不支持回放
|
客户端操作体验度(需要刷新等)
|
很好
|
好
|
低,需要刷新
|
能生成真实图像
|
可以支持
|
不支持
|
可以
|
运行性能(响应速度)
|
比较好
|
好
|
一般
|
从上面的几个方面比较可以看出这几种方式各有千秋,采用插件方式需要客户端安装了该插件才能使用,虽然插件的功能可以做的很强,用户用起来也会比较流畅,但是用户不一定会安装,因此这种方式比较适用于用户群比较少的场合。静态脚本方式由于只是实现了伪图像的编辑,因此不能称为真正的图像编辑,例如用JavaScript输出了一些点状“图像”,如果用户全选网页(Ctrl+A),往往机器会立刻死机,因此只能用于要求不高、支持作为临时画图的场合。从操作方便性、功能健壮性、程序可移植性等角度考虑,采用动态语言开发图像处理是比较好的选择。这种方式可以比较方便的生成一幅真正的图像,而且还支持图像的各种处理效果,但是由于需要不断地和服务器发生大量数据交互,因此用户响应速度很慢,国人开发的IEPhotoShop网站使用时更是证明了这一点。那什么样的方案能平衡这些优缺点,又能满足Web图像编辑的需求?现在我们还不清楚Adobe会采用什么样的方式来实现可托管的PhotoShop,但是DotNet的时代给图像处理带来了新的契机,尤其是.Net 2.0/3.0的不断发展,废话说了一堆,下面我将向大家介绍我实现Web图像编辑的方案及实施方法。
我的实现方案具体可用下面几个关键字来概括:
1
.静态脚本(Static Script)
结合脚本技术,例如JavaScript/VBScript等,可以实现在前台用户的图像绘制,虽然这时候绘制的图像还不是真正的图像,但是可以将绘制的点的坐标集记录下来。
2
.无刷新回调(CallBack)
如何将这些点传给服务器?如果采用普通的提交方式,会和服务器交互大量无用的信息,例如图像数据等,其实关键是只需要得到绘制点集。DotNet 2.0中实现的ICallBackHandle接口使之成为可能。当然也可以用Ajax来传输数据,考虑到稳定性等,个人建议可以基于该接口开发自己的回调。
3
.GDI Plus(GDI+)
服务器端收到这些信息后,可以对图像进行处理了。那么怎么处理呢?GDI+则可以实现您想要的任何效果。这里有人要发问了,基于GDI+的图像处理性能会不会很差?我只能说GDI+完全不等于GDI,如果保持好的编程习惯、结合一些GDI+优化方法(例如双缓存等),如果不是3D类应用,我想对于Web的图像处理应该足足够了!
4
.反射机制(Reflector)
反射机制在.Net应用中的地位很特殊,如果用得好,可以实现一些意想不到的效果。例如您可以很容易的实现第三方滤镜效果。!
到这里,不知道您是否理解了我的实现方案,如果您已经明白我的想法,也许您现在就可以实现这样的Web图像处理模型!如果还是不太清楚的话,那只能继续忍受更多的废话了~。现在我们结合下面的图形及一些实现代码来把这个方案更详细得描绘一下。
几个关键的代码示例:
①
通过
JavaScript
实现前台绘制图像的点集,并记录到全局的数组。代码如下:
var XPoints=new Array();
var YPoints=new Array();
//在坐标(x,y)点绘制一个虚拟的点
function doMakPoint(x,y)
{
//具体实现方法很多,例如输出一个像素大小的div
}
//例如绘制曲线,鼠标移动时生成点并记录点集
//对于绘制不同形状增加的点数不同,绘制矩形则只要记录两个对角点位置
//其他还要实现点集数组的清空等操作
function doMouseMove()
{
doMakPoint(event.x,event.y);
XPoints[XPoints.length]=x;
YPoints [YPoints.length]=y;
}
②
主要是实现无刷新回调,实现的方法比较简单,只要
IE
版本在
5.5
以上,均可以通过实现
ICallbackEventHandler
接口来完成回调,具体实现您可以从网上找到更为详尽的资料,基本代码如下:
[
后台
CS
代码部分
]
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//
定义前台回调代码
string ReceiveScript = @"
function ReceiveServerData(arg){
doReceiveDta(arg);
}";
ClientScript.RegisterClientScriptBlock(this.GetType(),
"ReceiveServerData", ReceiveScript, true);
string CallbackScript = @"
function CallTheServer(arg) {
if(arg!='')" +
ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", null) + @";
}";
ClientScript.RegisterClientScriptBlock(this.GetType(),
"CallTheServer", CallbackScript, true);
}
}
//
接收客户端消息
public void RaiseCallbackEvent(string eventArgument)
{
returnValue = doImgProcess(Server.UrlDecode(eventArgument));
}
//
返回客户端
public string GetCallbackResult(){return returnValue;}
public string doImgProcess(string argStr)
{
String strRtn=””;
String[] tmpStrAry = argStr.Split('@');
System.Drawing.Bitmap b = new Bitmap(100, 200);;
if(tmpStrAry[0]==”R”)//
绘制矩形
{
//
处理代码可以单独封装起来
b=Paint.DrawRect(b);
//
可以用
Session
等记录下当前图像,可用于更新前台
Img
的来源
Session[“curImg”]=b;
strRtn=”OK”;
}
return strRtn;
}
[
前台回调代码
]
③
是一系列的图像处理模块,这里可以充分利用
.Net
的强大功能,例如反射、
Web Service
等均可以,只要能返回一个图像实例就可以了。例如上面
DrawRect
的实现:
public static class
Paint
{
public static BitmapDrawRect(Bitmap b,String[]tmpStrAry)
{
using (Graphics g = Graphics.FromImage(b))
{
//
从
tmpStrAry
解析绘制位置信息
g.DrawRectangle(curPen, new Rectangle(…);
}
}
}
通过上面的解释我相信您应该明白了我的做法,这种方案和前面提到的几种实现方式比较最大的特点是:
1
)
IE
不需要安装任何插件
2
)用户操作犹如发生在本地
3
)可以实现更多图像的加工处理,具体的一些比较我将在后面再讨论。细心的读者会发现在
Ajax
的资料中有一个类似的例子,但是如果按照说明安装使用就会发现根本无法实际的绘制图形,响应速度也很慢,根本原因我估计和前台绘制的方法有关,因此我的这个方案中,前台的绘制信息处理时一个很关键的部分,网上有很多采用
Javascript
绘制点、线、图形的例子,但是要和后台绘制图形报纸精确,还是需要仔细斟酌的,例如:如果画一条直线,前台只要两个点的位置给后台,但是如果画笔宽度很宽,就会对位置由一定影响。当然上面只是实现方案的简单概括,能够实现一个用户能够使用的
Web
图像编辑器还需要做更多的工作!同时如果您对我的方案有更好的建议,希望能和我联系,我的联系方式是
QQ
:
12198613,MSN
:
[email protected]
,!