zoukankan      html  css  js  c++  java
  • Flash在线签名小程序,可回放,动态导出gif图片

    需求:

    公司为了使得和客户领导签字的时候记录下来,签字过程,可以以后动态回放演示,最好是gif图片,在网页上也容易展示,文件也小。

    解决过程

        始我们去寻找各种app,最终也没有找到合适的,后来我在flash8上看到有个在线的手绘板,很适合我们的需求,但是我尝试了很多次

    绘画完成后,导出的是swf文件,我想从这个swf文件中抽出图片,最终发现这个导出的swf里面根本不存在我绘画的记录过程。

    网上确实有手绘板的代码,但是没有动态回放的功能及到处gif图片的功能,还是不满足我们需求,

         索性自己写了一个flash小程序实现手绘画板及动态回放功能。我把具体的思路及详细代码都贴出来,

    希望能给有用到的人带来方便。

    整体思路:

    1. 编写一个flash程序,实现基本手绘板功能
    2. 在基础上实现回放功能(这里是难点)
    3. 创建一个asp.ne站点,写个一般处理程序GetSignImg.ashx,用于存储flash发布时候动态创建的jpg图片
    4. 当swf程序发布后点击下载的时候,后台程序将所有的jpg图片拼成gif图片导出(使用了Gif.Components.dll)。

    截图:

    具体过程

     一、实现手绘板功能,在网上能找到很多代码,这块也简单。

     二、在基础上实现回放功能,我重点讲下这里的实现,起初我是这么判断的,当鼠标MOUSE_DOWN时候开始记录画笔当前位置信息存入一个数组中(包含X,Y坐标值),

         鼠标MOUSE_UP的时候,这个数组存储结束,开启一个新的数组用于点的信息。当回放的时候,将这些所有数组中的点的信息重新绘制一遍,包括flash8.net的实现都是这么干的

         如果一笔绘制很长,当它回放的时候一下子全显示出来,没有一个绘制的过程。后来领导说这样不行,因为领导签字的时候很多都是一笔走完,最后我想了一个解决的办法,

         就是在回放的时候设置一个阀值,比如50个点,够50个点就回放一次,这样一来,即使领导签字是一笔,回放的时候效果也会很好。

        下面是所有ActinScipt源码

       

      1 import flash.ui.Mouse;
      2 import flash.display.BitmapData;
      3 import com.adobe.images.JPGEncoder;
      4 import flash.events.MouseEvent;
      5 
      6 var linesize:uint = 2;//画笔大小
      7 var isDown:Boolean = false;
      8 var oldX:Number;
      9 var oldY:Number;
     10 var arrayBig:Array=new Array();//存放笔画的数组,外层数组
     11 var num:uint = 0;//当前数组个数
     12 var playNum:uint = 0;//当前回放的数字(代表当前回放到第几个数组了)
     13 var intervalDuration:Number = 500;// 回放延时时间间隔
     14 var relaseDuration:Number = 1000;//发布时时间间隔
     15 var intervalId:uint;//回放循环的ID 
     16 var relaseId:uint;//发布的ID
     17 var url = "http://www.wispdawn.com/";//暂用我的网站做服务器
     18 var serviceFile = "GetSignImg.ashx";//服务文件
     19 
     20 mc_canvas.addEventListener(MouseEvent.MOUSE_DOWN ,onDown);
     21 mc_canvas.addEventListener(MouseEvent.MOUSE_UP ,onUp);
     22 mc_canvas.addEventListener(MouseEvent.MOUSE_MOVE ,onMove);
     23 mc_canvas.addEventListener(MouseEvent.MOUSE_OVER,onMouseOver);
     24 mc_canvas.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut);
     25 
     26 
     27 
     28 function onDown(event:MouseEvent):void
     29 {
     30     arrayBig[num]=new Array();//这里设置为数组
     31     isDown = true;
     32     oldX = mouseX;
     33     oldY = mouseY;
     34 }
     35 function onMove(event:MouseEvent):void
     36 {
     37     if (isDown)
     38     {
     39         mc_canvas.graphics.lineStyle(linesize);
     40         mc_canvas.graphics.moveTo(oldX,oldY);
     41         mc_canvas.graphics.lineTo(mouseX,mouseY);
     42         oldX = mouseX;
     43         oldY = mouseY;
     44         arrayBig[num].push([oldX,oldY]);
     45         if (arrayBig[num].length > 80)
     46         {
     47             //isDown = false;
     48             trace(num);
     49             num++;//数组个数+1
     50             arrayBig[num]=new Array();
     51             arrayBig[num].push([oldX,oldY]);
     52         }
     53     }
     54 }
     55 
     56 function onUp(event:MouseEvent):void
     57 {
     58     isDown = false;
     59     trace(num);
     60     num++;//数组个数+1
     61 }
     62 
     63 function onMouseOver(event:MouseEvent):void
     64 {
     65     mc_canvas.addEventListener(Event.ENTER_FRAME, onEnter);
     66 }
     67 
     68 
     69 function onMouseOut(event:MouseEvent):void
     70 {
     71     mc_canvas.removeEventListener(Event.ENTER_FRAME, onEnter);
     72     Mouse.show();
     73     mc_pen.visible = false;
     74 }
     75 
     76 //画布监听事件
     77 function onEnter(event:Event):void
     78 {
     79     Mouse.hide();
     80     mc_pen.visible = true;
     81     mc_pen.x = mouseX + 22;
     82     mc_pen.y = mouseY + 22;
     83 }
     84 
     85 
     86 
     87 //清空
     88 btn_clear.addEventListener(MouseEvent.CLICK,onClear);
     89 function onClear(event:MouseEvent):void
     90 {
     91     arrayBig = [];
     92     playNum = 0;
     93     num = 0;
     94     mc_canvas.graphics.clear();
     95 }
     96 //保存;
     97 btn_save.addEventListener(MouseEvent.CLICK,onSave);
     98 function onSave(event:MouseEvent):void
     99 {
    100     var imager:BitmapData = new BitmapData(mc_canvas.width,mc_canvas.height);
    101     imager.draw(mc_canvas);
    102     var jpg:JPGEncoder = new JPGEncoder(100);
    103     var file:FileReference = new FileReference();
    104     file.save(jpg.encode(imager),"sign.jpg");
    105 
    106 }
    107 
    108 //回放按钮
    109 btn_replay.addEventListener(MouseEvent.CLICK,onReplay);
    110 function onReplay(event:MouseEvent):void
    111 {
    112     if (arrayBig.length > 0)
    113     {
    114         mc_canvas.graphics.clear();
    115         //清除画面;
    116         playNum = 0;//初始为0
    117         intervalId = setInterval(onReplayDelay,intervalDuration);
    118     }
    119 }
    120 
    121 //用于设置循环的回放
    122 function onReplayDelay():void
    123 {
    124     //当前笔画
    125     var arr:Array = arrayBig[playNum];
    126     //当前笔画下面所有的点
    127     for (var i:uint=0; i<arr.length-1; i++)
    128     {
    129         var curPoint = arr[i];
    130         var nexPoint = arr[i + 1];
    131         mc_canvas.graphics.lineStyle(linesize);
    132         mc_canvas.graphics.moveTo(curPoint[0],curPoint[1]);
    133         mc_canvas.graphics.lineTo(nexPoint[0],nexPoint[1]);
    134     }
    135 
    136     playNum++;
    137     if (playNum==num)
    138     {
    139         clearInterval(intervalId);
    140     }
    141 }
    142 
    143 //上传图片
    144 function UpImg(seq:uint):void
    145 {
    146     var imager:BitmapData = new BitmapData(mc_canvas.width,mc_canvas.height);
    147     imager.draw(mc_canvas);
    148     var jpg:JPGEncoder = new JPGEncoder(100);
    149     var bytes:ByteArray = jpg.encode(imager);
    150 
    151     var signName:String = mc_mask.txt_name.text;
    152     var req:URLRequest = new URLRequest(url+serviceFile+"?name="+signName+"&seq="+seq+"&total="+arrayBig.length);
    153     req.data = bytes;
    154     req.method = URLRequestMethod.POST;
    155     req.contentType = "application/octet-stream";
    156 
    157     var loader:URLLoader = new URLLoader();
    158     loader.dataFormat = URLLoaderDataFormat.BINARY;
    159     loader.load(req);
    160 }
    161 //loader.addEventListener(Event.COMPLETE, completeHandler);
    162 
    163 //function completeHandler(evt:Event):void
    164 //{
    165 //trace(evt.target.data);
    166 //}
    167 
    168 //发布
    169 btn_release.addEventListener(MouseEvent.CLICK,onReleas);
    170 function onReleas(event:MouseEvent):void
    171 {
    172     if (arrayBig.length > 0)
    173     {
    174         mc_mask.x = mc_mask.y = 0;
    175         mc_mask.mc_mask_bg.alpha = 0.8;
    176         mc_mask.btn_complete.visible = false;//隐藏完成
    177         mc_mask.btn_down.visible = false;//隐藏下载
    178     }
    179 }
    180 //真正发布事件执行
    181 function Release():void
    182 {
    183     //当前笔画
    184     var arr:Array = arrayBig[playNum];
    185     //当前笔画下面所有的点
    186     for (var i:uint=0; i<arr.length-1; i++)
    187     {
    188         var curPoint = arr[i];
    189         var nexPoint = arr[i + 1];
    190         mc_canvas.graphics.lineStyle(linesize);
    191         mc_canvas.graphics.moveTo(curPoint[0],curPoint[1]);
    192         mc_canvas.graphics.lineTo(nexPoint[0],nexPoint[1]);
    193     }
    194     //上传图片;;
    195     UpImg(playNum);
    196     playNum++;
    197     if (playNum==num)
    198     {
    199         clearInterval(relaseId);
    200         AfterRelease();
    201     }
    202 }
    203 //取消发布
    204 mc_mask.btn_cancel.addEventListener(MouseEvent.CLICK,onCancel);
    205 function onCancel(event:MouseEvent):void
    206 {
    207     mc_mask.x = 10000;
    208     mc_mask.mc_mask_bg.alpha = 0;
    209 }
    210 //真正发布按钮
    211 mc_mask.btn_release.addEventListener(MouseEvent.CLICK,onTrueRelease);
    212 function onTrueRelease(event:MouseEvent):void
    213 {
    214     var name1 = mc_mask.txt_name.text;
    215     if (name1!="")
    216     {
    217         BeginRelease();
    218         mc_canvas.graphics.clear();
    219         playNum = 0;
    220         relaseId = setInterval(Release,relaseDuration);
    221     }
    222     else
    223     {
    224         mc_mask.txt_state.text = "请输入姓名";
    225     }
    226 }
    227 //发布前设置
    228 function BeginRelease():void
    229 {
    230     mc_mask.btn_release.visible = false;
    231     mc_mask.btn_cancel.visible = false;
    232     mc_mask.txt_name.visible = false;
    233     mc_mask.txt_nameTile.visible = false;
    234     mc_mask.txt_state.text = "正在发布...";
    235 }
    236 //发布后设置
    237 function AfterRelease():void
    238 {
    239     mc_mask.btn_complete.visible = true;
    240     mc_mask.btn_down.visible = true;
    241     mc_mask.btn_complete.addEventListener(MouseEvent.CLICK,onComplete);
    242     mc_mask.txt_state.text = "发布完成";
    243 
    244 }
    245 //发布完成
    246 function onComplete(event:MouseEvent):void
    247 {
    248     mc_mask.x = 10000;
    249     mc_mask.mc_mask_bg.alpha = 0;
    250     mc_mask.btn_down.visible = true;
    251     mc_mask.btn_release.visible = true;
    252     mc_mask.btn_cancel.visible = true;
    253     mc_mask.txt_name.visible = true;
    254     mc_mask.txt_nameTile.visible = true;
    255     mc_mask.txt_state.text = "";
    256     mc_mask.txt_name.text = "";
    257 }
    258 
    259 //下载gif
    260 mc_mask.btn_down.addEventListener(MouseEvent.CLICK,onDownGif);
    261 function onDownGif(event:MouseEvent):void
    262 {
    263     var today:Date =new Date();
    264     var todayStr = getDateFormat(today);//获取当天日期例如 20131130
    265     var signName:String = mc_mask.txt_name.text;
    266 
    267     var gifUrl:URLRequest = new URLRequest(url+"/Img/"+signName+"_"+todayStr+"/"+signName+".gif");
    268     var fileRef:FileReference=new FileReference();
    269     //fileRef.addEventListener(ProgressEvent.PROGRESS,onProgress);
    270     fileRef.download(gifUrl,"sign.gif");
    271 }
    272 function onProgress(event:ProgressEvent):void
    273 {
    274     var loaded:uint = event.bytesLoaded;
    275     var total:uint = event.bytesTotal;
    276 }
    277 
    278 //获取当天日期
    279 function getDateFormat( date:Date):String
    280 {
    281     var dYear:String = String(date.getFullYear());
    282     var dMonth:String = String((date.getMonth() + 1 < 10) ? "0" : "") + (date.getMonth() + 1);
    283     var dDate:String = String(date.getDate() < 10 ? "0":"") + date.getDate();
    284     return dYear+dMonth+dDate;
    285 }
    View Code

     三、创建一个asp.ne站点,写个一般处理程序GetSignImg.ashx

           这里就是用于的获取flash传递过来的图片,获取后导出jpg图片序列,然后将这些序列图片用程序生成一个gif图片存放在目录下,当flash点击到处gif图片时候,执行下载

           源文件如下

          

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Web;
     5 using System.IO;
     6 using System.Drawing.Drawing2D;
     7 using System.Drawing.Imaging;
     8 using Gif.Components;
     9 
    10 namespace Web
    11 {
    12     /// <summary>
    13     /// GetSignImg1 的摘要说明
    14     /// </summary>
    15     public class GetSignImg1 : IHttpHandler
    16     {
    17         public void ProcessRequest(HttpContext context)
    18         {
    19             string name = context.Request["name"];
    20             int seq = Convert.ToInt32(context.Request["seq"]);
    21             int total =Convert.ToInt32(context.Request["total"]);
    22             int length = context.Request.TotalBytes;
    23             byte[] buffer = context.Request.BinaryRead(length);
    24             string newPath=HttpContext.Current.Server.MapPath("Img/" + name + "_"+DateTime.Now.ToString("yyyyMMdd"));
    25             if (!Directory.Exists(newPath))
    26             {
    27                 Directory.CreateDirectory(newPath);
    28             };
    29             string path = string.Format("{0}/{1}.jpg", newPath, seq);
    30             FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
    31             BinaryWriter bw = new BinaryWriter(fs);
    32             bw.Write(buffer);
    33             bw.Close();
    34             fs.Close();
    35 
    36             //下载gif
    37             if (seq + 1 == total)
    38             {
    39                 //生成gif图片               
    40                 List<string> fileList = new List<string>();
    41                 for (int i = 0; i < total; i++)
    42                 {
    43                     fileList.Add(newPath + "/" + i + ".jpg");
    44                 }
    45                 string[] imageFilePaths = fileList.ToArray();
    46                 string outputFilePath = newPath + "/" + name + ".gif";
    47                 AnimatedGifEncoder e = new AnimatedGifEncoder();
    48                 e.Start(outputFilePath);
    49                 //图片转换时间
    50                 e.SetDelay(50);
    51                 //1表示只动一次,0:表示循环,n:表示循环n次
    52                 e.SetRepeat(1);
    53                 for (int i = 0, count = imageFilePaths.Length; i < count; i++)
    54                 {
    55                     e.AddFrame(System.Drawing.Image.FromFile(imageFilePaths[i]));
    56                 }
    57                 e.Finish();
    58             }
    59         }
    60 
    61         public bool IsReusable
    62         {
    63             get
    64             {
    65                 return false;
    66             }
    67         }
    68     }
    69 }
    GetSignImg.ashx.cs

     四、所有程序打包下载 Download

  • 相关阅读:
    基于javascript引擎封装实现算术表达式计算工具类
    Windows 服务入门指南
    参数化查询为什么能够防止SQL注入
    Control 的DraggerHelper, 拖动控件从此变得很简单。。。
    书籍推荐记这几年看的书
    使用“using” 的 “Cursor”
    多线程,silverlight_Rest_WCF,dynamic 索引帖
    关于静态事件 static event 的二三事
    探讨 .NET 4 新增的 SortedSet 类
    我们需要莱特希尔报告
  • 原文地址:https://www.cnblogs.com/clc2008/p/3574899.html
Copyright © 2011-2022 走看看