外行眼中的绝版木刻

Silverlight从其余系统得到外部数据的常规途径只有下面2种:
1、直接远程加载文本或xml文件
(直接呼吁ashx/aspx,然后在ashx/aspx上输出信息也足以归入这一类)

多少个月前的某一天,在中学同学微信群里探究一个有关家乡思茅值得骄傲的绝版木刻话题,据说因其独特的良方并多次拿到全国金奖而著名全国。因为外孙女正在上学壁画,所以对此相比较关心,趁暑期回思茅的空子,在高中同学的推介下,带外孙女拜访了几位绝版木刻大师,中远距离欣赏绝版木刻作品,感受家乡艺术奇葩的影响,开了见识也长了见识。

2、通过wcf/webService(Service)取得数据

绝版木刻是木刻中的一种,其全称应为:油印套色木刻。上世纪80年代末发源于山西思茅,以张晓春、贺昆、马力等人为表示的一批戏剧家创立了一种不同于其他木刻模式的新秘诀,它突破了观念套色木刻的造作程序和审美观念,将一幅画所有的色版都会聚在一块版上,采纳边刻边印逐版递减的编写方法来完成,刻印油画的长河也是自然毁版的过程,不可以逆袭,著作形成后原版已力不从心再印出随笔,由此被叫做“绝版木刻”,它可密切入微地勾画亦能中度概括,具有极强的表现力。思茅音乐家张晓春、贺昆、马力等人的绝版木刻小说多次拿到全国金奖,因此思茅绝版木刻享誉全国、走向世界,成为思茅一张重要的名片,曾传闻有句俗语说家乡的四道大菜是“绝版木刻防城港茶、豆浆米干大红菌”……

(当然,sl跟本机的sl之间也能互换数据,但以此用处有限,另外通过socket也能得到数码,可是socket要玩好并不便于,难度周到有点高,本文不做商讨)

谢谢高中同学的热忱推介和精心安排,使我们有幸认识纸版木刻的三位代表人士张晓春、贺昆、马力,并到他们的工作室参观学习,外孙女能向她们求教创作技法、享受艺术盛宴,而我们也随即学习了绝版木刻的一些基本知识,在看热闹的还要也有些了然了一点点浅显的途径……

而回到的多少格式,最常用的平凡为”xml”、”json字符串”(或普通字符串) 或
“最原始的Stream”

一进来张晓春工作室,就能感受到浓浓的艺术气息,屋内散发着油墨的馥郁,门前小院精致淡雅的园艺小品、休闲的桌椅特别养眼……墙上挂满了张先生的文章,远看金色华丽、近看生动细腻,戴着棕色宽边眼镜的张晓春儒雅、干练,说话不紧不慢,以一个艺术家的理念、专业老师的言语将绝版木刻的作文历程娓娓道来:首先就要创作的画稿印在中密度小小的木板上;第二步,遵照图画的情调和线条确定每一步骤刻制的情节,完成之后展开一道油印;第三步,将上一道油印留在版上的痕迹清理彻底,再开展下一色彩的刻制,再开展一道油印,如此循环重复,直到完成随笔的整套作文。遵照作品的情节不同,每幅壁画小说的刻制、油印程序少则10道、多则数十道,第一道油印程序的印制数量确定每一幅著作的最大数据,书墨家们会按照随笔的始末、艺术价值、刻制印刷工作量等元一直支配每幅小说的印制数量。每一道油印过程都在画纸上加码一道色彩,同时与上一道油印的色彩混合后发出新的颜料,通过若干道细致、繁琐的刻制、油印程序,一幅精美的木刻著作就诞生了,充裕的情调及组成、细致的探究技法使文章具有了增长的表现力和斑斓的情调,且不说撰写一幅小说时独具匠心的方法构思,光看戏剧家们在难得的木板上一刀一刀细致的镂空、油墨使用、清洗的技艺、木版防油墨渗漏的操纵等等就无不侧目不已……张晓春的创作细腻、唯美,让眼睛很舒适的金黄色基调、有浓南渡河苏民族特色的美术内容都让人舒心,尤其是他著述中的人物更令人映像浓密……

 

贺昆的工作室“古道博客”不仅仅是工作室的概念,更是一个多重艺术的显示中央,听说里头的建筑、园艺都是由贺昆自己规划的,戏剧家的意见就是异常,砖块、木头、金属废料……各样不起眼的资料构成在一起就能给人不一般的感觉到,工作室里造型别致、独一无二的实木椅子、阳台栏杆上生长着的木耳都掀起了我们的见解……肢体稍微发福的贺昆戴顶草帽出现在大家眼前,如若在街上见到一定认为是个刚从田地里工作回来的农家……他很有趣、也很健谈,一会儿是名不虚传的思茅口音,一会儿是带浓重京腔后鼻音的国语,只差几句London口音的荷兰语了,将她北漂、海外游学的经历与清醒与我们大饱眼福,他创作里鲜艳的情调、瑰丽斑斓的镜头令人难忘……

前几日在读书FluorineFx(一个开源的免费项目),并查看它的示范示例时,意外发现FluorineFx也辅助silverlight!

空山水墨画大旨是另一个表示人物马力的工作室,起名源自王维诗句“空山新雨后,天气晚来秋”。工作室的形式如它的名字如出一辙自有一种山水田园、怡然自得的意象。马力著作给自己映像深远的是山水画,近看是多少个细小三角色块的重组,远看却是磅礴大气却不失柔美的镜头,让你的肉眼特别享受……在工作室里现场观战素描油印程序,遇见刚从肯尼亚国旅归来的马力,为我们的绝版木刻欣赏之旅扩张了色彩……

 

观赏出色的绘画、看不错的山色真是人生一大乐事,对于老百姓而言,取一份平静的心思、放慢匆匆的步子,细细品味路过的所有,或许会是描写好景象的最好画笔了……

与webService(Service)接纳的soap协议不同:FluorineFx扶助Adobe的AMF0,AMF3,RTMP协和,能有利于的与Adobe几乎所有的简报技术并行,这为silverlight与flash/flex交互提供了说不定。(详见百度百科FluorineFX
http://baike.baidu.com/view/1654458.htm?fr=ala0_1)

下面简单说下silverlight中应用FluorineFx的大体步骤:

大抵
silverlight本身只是一种UI技术,自身并无太强的的数目处理能力(独立存储尽管提供了数据存储和查找能力,但力量实际有限),要获取数据只好依靠任何系统或技术,所以大家先把其余系统做好:

 

1、先用VS.Net(我用的是vs2010)创设一个Library项目,起名为ServiceLib,并在其间创设一个TestLib.cs的类,代码如下:

using System.ComponentModel;
using System.Data;
using FluorineFx;

namespace ServiceLib
{
    [RemotingService]
    [Description("Test Service")]
    public class TestLib
    {
        [DataTableType("SliverlightApp.Person")]
        public DataTable GetPersonList()
        {
            DataTable tbl = new DataTable();
            tbl.Columns.Add("Name", typeof(string));
            tbl.Columns.Add("Age", typeof(System.Int32));
            tbl.Rows.Add("菩提树下的杨过", 30);
            tbl.Rows.Add("小龙女", 100);
            return tbl;
        }
    }
}

自然,这一个序列要引用FluorineFx程序集,该项目标重中之重意图在于把”取多少”的工作逻辑封装在这一层,以有益重用。

 

2、再创制一个webApplication,起名为WebApp,同样要添加FluorineFx.dll的引用

  2.1
然后创制一个名为Gateway.aspx的文本,那样就行了,不用添加另外多余的代码(这个文件作为调用FluorineFx的网关)

  2.2
在根目录下,成立目录Web-INF/flex
(即二层目录),然后在flex目录下,放置一个services-config.xml,内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<services-config>
  <services>
    <service id="remoting-service" class="flex.messaging.services.RemotingService" 

messageTypes="flex.messaging.messages.RemotingMessage">
      <destination id="fluorine">
        <channels>
          <channel ref="my-amf"/>
        </channels>
        <properties>
          <source>*</source>
        </properties>
      </destination>
    </service>
  </services>

  <channels>
    <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
      <endpoint uri="http://{server.name}:{server.port}/{context.root}/Gateway.aspx" 

class="flex.messaging.endpoints.AMFEndpoint"/>
      <properties>
        <!-- <legacy-collection>true</legacy-collection> -->
      </properties>
    </channel-definition>
  </channels>
</services-config>

抄送就好了,不用管太多。基本上那个布局的效益就相当于添加wcf(svc文件)后,系统活动在web.config中加进的部署节点,用于提供部分必要的部署音信.

 
2.3修改web.config的httpModules节点为以下内容 

<httpModules>
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add name="FluorineGateway" type="FluorineFx.FluorineGateway, FluorineFx"/>
</httpModules>

  2.4 添加对Service(Service)Lib项目标引用

 

3、最后创建一个silverlight项目,添加FluorineFx.dll引用,命名为SliverlightApp

专注:FluorineFx.dll有二个本子,一个用于webform,一个专用于silverlight(本文最终会提交下载)

一般说来用vs.net创设一个silverlight项目时,会唤醒您是不是把该类型承载于一个webApplication项目中,以有利于测试,这里直接指定第2步中的webApp为承接项目(即一对一于webApp项目增长对SliverlightApp的引用)

 

在silverlight中访问FluorineFx的首要代码如下:

using FluorineFx;
using FluorineFx.AMF3;
using FluorineFx.Messaging.Api.Service;
using FluorineFx.Net;

...

//点击按钮时,开始调用
private void btnFluorineFx_Click(object sender, RoutedEventArgs e)
        {
            NetConnection _netConnection = new NetConnection();
            _netConnection.ObjectEncoding = ObjectEncoding.AMF3;
            _netConnection.NetStatus += new NetStatusHandler(_netConnection_NetStatus);
            _netConnection.Connect("http://localhost:1718/Gateway.aspx");
            _netConnection.Call("ServiceLib.TestLib.GetPersonList", new GetPersonHandler(this));

        }

//状态回调
private void _netConnection_NetStatus(object sender, NetStatusEventArgs e)
        {
            string level = e.Info["level"] as string;
            this.Dispatcher.BeginInvoke(() => { this.txtResult.Text = "level:" + level + ",code:" + e.Info

["code"] as String; });

        }


//数据回调处理
private class GetPersonHandler : IPendingServiceCallback
        {
            MainPage page;

            public GetPersonHandler(MainPage page)
            {
                this.page = page;
            }

            public void ResultReceived(IPendingServiceCall call)
            {
                page.Dispatcher.BeginInvoke(() => { page.txtResult.Text = ""; });
                object result = call.Result;
                ArrayCollection items = result as ArrayCollection;
                foreach (object item in items)
                {
                    Person p = item as Person;//注意:这里直接将数据反序列化为Person了

                    page.Dispatcher.BeginInvoke(() => { page.txtResult.Text += p.ToString() + ";"; });          


                }

            }
        }

理所当然还有一个数额实体类Person.cs

using System;

namespace SliverlightApp
{
    public class Person
    {
        public string Name { set; get; }
        public int Age { set; get; }

        public override string ToString() {
            return "name:" + Name + ",age:" + Age.ToString();
        }
    }
}

4、最终回过头来,在webApp中把(创立silverlight项目时自动生成的)SliverlightAppTestPage.aspx设置为启动页测试就行了

总体解决方案的目录结构如下:

 图片 1

分析:

价值观的soap协议是应用xml格式的,而xml格式的最大问题就是数额太大,比如一个普普通通的”hello
world”字符串,经过xml格式封装后,可能变成<string>hello world</string>,再加上文件头部的xml文档注明,传输数据量最终会追加很多。

为了精益求精,Adobe发明了AMF0/AMF3琢磨,AMF是Adobe独家开发出来的通信协议,它应用二进制压缩,序列化、反体系化、传输数据,从而为Flash
播放器与Flash Remoting网关通信提供了一种轻量级的、高效率的通信情势。

故此FluorineFx相对于基于soap协议的web
service/wcf而言,应该是效率会更高,不过大家也应该看到微软的前进:wcf在传输数据时,除了xml格式,还足以用json格式甚至一贯最原始的stream流格式。为了相比,我在代码中还专门加了test.svc
以json格式重回数据,用于跟fluorinefx做下比较(xml格式就懒得相比较了,传输数据量肯定要超过json格式)–test.svc里的具体代码如下:

using System.Collections.Generic;
using System.Data;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;

namespace WebApp
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class test
    {

        /// <summary>
        /// 利用系统自动封装成json格式
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]
        public List<SliverlightApp.Person> GetPersonList()
        {
            List<SliverlightApp.Person> lst = new List<SliverlightApp.Person>();
            lst.Add(new SliverlightApp.Person() { Name = "菩提树下的杨过", Age = 30 });
            lst.Add(new SliverlightApp.Person() { Name = "小龙女", Age = 100 });
            return lst;
        }

        /// <summary>
        /// 自己封装成json格式
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        [WebInvoke(Method = "GET")]
        public Stream GetPersonList2()
        {
            DataTable tbl = new DataTable();
            tbl.Columns.Add("Name", typeof(string));
            tbl.Columns.Add("Age", typeof(System.Int32));
            tbl.Rows.Add("菩提树下的杨过", 30);
            tbl.Rows.Add("小龙女", 100);
            return GetStream(CreateJsonParameters(tbl));
        }


        /// <summary>
        /// 将datatable转化成json字符串
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        private string CreateJsonParameters(DataTable dt)
        {            
            StringBuilder JsonString = new StringBuilder();                   
            if (dt != null && dt.Rows.Count > 0)
            {
                JsonString.Append("{ ");
                JsonString.Append("\"Head\":[ ");
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    JsonString.Append("{ ");
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        if (j < dt.Columns.Count - 1)
                        {
                            JsonString.Append("\"" + dt.Columns[j].ColumnName.ToString().Replace("\"", "\\\"") + "\":" + "\"" + dt.Rows[i][j].ToString().Replace("\"", "\\\"") + "\",");
                        }
                        else if (j == dt.Columns.Count - 1)
                        {
                            JsonString.Append("\"" + dt.Columns[j].ColumnName.ToString().Replace("\"", "\\\"") + "\":" + "\"" + dt.Rows[i][j].ToString().Replace("\"", "\\\"") + "\"");
                        }
                    }

                    if (i == dt.Rows.Count - 1)
                    {
                        JsonString.Append("} ");
                    }
                    else
                    {
                        JsonString.Append("}, ");
                    }
                }
                JsonString.Append("]}");
                return JsonString.ToString();
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 辅助方法,用于输出流
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private Stream GetStream(string str)
        {
            MemoryStream ms = new MemoryStream();
            StreamWriter sw = new StreamWriter(ms);
            sw.AutoFlush = true;
            sw.Write(str);
            ms.Position = 0;
            WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
            return ms;
        }
    }
}

图片 2

这是用httpwatch在firefox下测试的结果:

如果用最原始的stream方法封装json数据,再次来到的数额为

图片 3

万一用系统提供的json自动封装,再次来到的多寡为

图片 4

而FluorineFx是以二进制再次来到的,不便利间接观看字符串,只可以向来反序列化为Peron类,就不贴出结果了。

从运行图的Received列上可以看看:“FluorineFx再次来到的数据大小-375” 要自愧不如“wcf默认封装的json数据-389”,但超越“开发者自行处理的json数据大小-312”

再相比提姆(Tim)e列,FluorineFx所用的岁月是不大的(当然多测试五回,结果稍有例外,但因此我的一再着眼,FluorineFx所花的时间一向是微小的)

 

概括比较下来:FluorineFx传输的数额小,传输时间短,全部效用是无可非议的,确实是silverlight/.net与此外系统神速传输数据的可选格局之一。

文中所用源代码下载:http://cid-2959920b8267aaca.office.live.com/self.aspx/Silverlight/FluorineFx.rar

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图