玩过截图的人都知道截图是怎样一回事,通过截取图片一个地方就能够获取到图片某一个片段。这一个部分在flash 里面可以利用位图的复制像素来实现。通过copyPixels 或者draw 能够获取像素。
现在我们讨论一个话题:在flash里面怎样实现这种截图? 带着这个问题,尝试制作一个demo出来。功能就是获取位图。
所需要的材料:第一就是flash绘图API ,第二就是位图像素操作。利用这两个我们就能够实现出这种交互效果。
设计的图案:
制作思路:首先知道怎样绘制一个矩形,可以上网搜索一下,或者查询一些flash绘图API 是如何操作的。借助绘制这股矩形,我们就能截取到我们所需要的片段。
接下来,为程序写一个基类:Item.as
定义一些常用的方法和属性。
例如绘制矩形。获取位图,定义线条的样式等,判断矩形是否有效
这些方法都是定义在这个基础类当中。
package org.summerTree { //选择类基本设置 import flash.display.Sprite; import flash.geom.Rectangle; import flash.events.EventDispatcher; import flash.display.Bitmap; import flash.display.BitmapData; import flash.geom.Point; public class Item extends EventDispatcher { public var LineColor:int=0x0000ff;//线条颜色 public var FillColor:int=0x0000ff;//填充的颜色 public var FillAlpha:Number=0.1; public function Item() { } //绘制矩形的基本方法 protected function DrawRect(shape:Sprite,rect:Rectangle):void { shape.graphics.clear(); shape.graphics.lineStyle(1,LineColor,1); shape.graphics.beginFill(FillColor,FillAlpha); shape.graphics.drawRect(rect.x,rect.y,rect.width,rect.height); shape.graphics.endFill(); } //判断rect是否有效 public function checkRect(rect:Rectangle):Boolean { return rect != null?true:false; } //定义样式 public function setStyle(lcolor:int,fcolor:int,aplha:Number):void { this.LineColor=lcolor; this.FillColor=fcolor; this.FillAlpha=aplha; } //获取位图 public function getImage(source:Bitmap,rect:Rectangle):Bitmap { var bitmapdata:BitmapData = source.bitmapData; var Width:Number=Math.abs(rect.width); var Height:Number=Math.abs(rect.height); var temp:Rectangle; var newImage:BitmapData; if (rect.width>0 && rect.height>0) { newImage=new BitmapData(Width,Height, false);// newImage.copyPixels(bitmapdata,rect,new Point(0,0)); } else if (rect.width<0 && rect.height>0) { newImage=new BitmapData(Width,Height, false);// temp=new Rectangle(rect.x-Width,rect.y,Width,Height); newImage.copyPixels(bitmapdata,temp,new Point(0,0)); } else if (rect.width<0 && rect.height<0) { newImage=new BitmapData(Width,Height, false);// temp=new Rectangle(rect.x-Width,rect.y-Height,Width,Height); newImage.copyPixels(bitmapdata,temp,new Point(0,0)); } else if (rect.width>0 && rect.height<0) { newImage=new BitmapData(Width,Height, false);// temp=new Rectangle(rect.x,rect.y-Height,Width,Height); newImage.copyPixels(bitmapdata,temp,new Point(0,0)); } return new Bitmap(newImage); } } }
基本接口:获取矩形,裁剪位图,取消操作,命令监听
package org.summerTree { import flash.geom.Rectangle; import flash.display.Bitmap; public interface ISelector { function getRect2D():Rectangle; function CutIamge(source:Bitmap):Bitmap; function Cancel():void; function addActionListener():void; } }
通过继承这个类实现一个接口,创建如何去选取位图
这个过程当中需要使用绘图API,首先通过鼠标交互绘制一个矩形,这个矩形通过drawRect来进行绘制。
当中对一些矩形进行拖放,和矩形拉伸 则需要通过重新绘制来获取到。这里主要涉及到技术就是绘图API 和鼠标交互。当中没有很难的技术点。关键的地方 使用Rectangle 的使用上,从这个案例当中你会发现这个类会帮助你实现 截图功能。
public class Selector extends Item implements ISelector 这样实现接口方式书写。
我们需要知道怎样通过鼠标交互拖放的时候影响矩形的大小,拉伸和缩放的时候,其实Rectangle 矩形会发生改变,通过这个对象能够获取他的坐标,宽度和高度,从而重绘制矩形带来一定帮助。
思路就是这样。
package org.summerTree { //version 1.0 裁剪类,对位图进行裁剪 //写于2010 年 1月30日 import flash.display.Sprite; import flash.display.DisplayObjectContainer; import flash.events.*; import flash.geom.*; import flash.display.Bitmap; import flash.display.BitmapData; import flash.utils.ByteArray; import flash.display.Stage; import org.summerTree.button.SButton;//缩放按钮 import org.summerTree.button.ButtonBar;//确定和取消按钮 import org.summerTree.button.ButtonPath; import org.summerTree.Item; import org.summerTree.event.SelectEvent; import org.summerTree.ISelector; public class Selector extends Item implements ISelector { private var point:Point;//记录一个定点 private var target:DisplayObjectContainer;//裁剪的对象 private var rect:Rectangle; private var pen:Sprite=new Sprite(); private var button:SButton;//选择类的按钮 private var buttonOk:ButtonBar=new ButtonBar();//确定按钮 private var buttonCannel:ButtonBar=buttonOk.clone();//取消按钮 private var isMove:Boolean=false; private var mystage:Stage; public function Selector(target:DisplayObjectContainer,stage:Stage) { this.target=target;//选择的对象 this.target.addChild(pen); this.mystage=stage; } public function addActionListener():void { target.addEventListener(MouseEvent.MOUSE_DOWN,DrawingHandler); } private function DrawingHandler(event:MouseEvent):void { switch (event.type) { case MouseEvent.MOUSE_DOWN : point=new Point(this.target.mouseX,this.target.mouseY); target.addEventListener(MouseEvent.MOUSE_MOVE,DrawingHandler); mystage.addEventListener(MouseEvent.MOUSE_UP,DrawingHandler); break; case MouseEvent.MOUSE_MOVE : rect=new Rectangle(point.x,point.y,target.mouseX - point.x,target.mouseY - point.y); trace(rect); DrawRect(pen,rect); event.updateAfterEvent(); break; case MouseEvent.MOUSE_UP : trace("执行这里"+target.parent.parent); target.removeEventListener(MouseEvent.MOUSE_MOVE,DrawingHandler); mystage.removeEventListener(MouseEvent.MOUSE_UP,DrawingHandler); target.removeEventListener(MouseEvent.MOUSE_DOWN,DrawingHandler); creatButton(); startdragRect();//拖动巨型 break; default : //isMove=false; break; } } //创建按钮,并对按钮进行监听 private function creatButton():void { if (checkRect(rect)) { button=new SButton(); buttonOk.addButton(ButtonPath.Btn_ok); buttonCannel.addButton(ButtonPath.Btn_cannel); this.target.addChild(button); this.target.addChild(buttonOk); this.target.addChild(buttonCannel); button.addEventListener(MouseEvent.MOUSE_DOWN,buttonDownHandler); buttonOk.addEventListener(MouseEvent.MOUSE_DOWN,buttonDownHandler); buttonCannel.addEventListener(MouseEvent.MOUSE_DOWN,buttonDownHandler); button.name="dragbutton"; buttonOk.name="buttonOk"; buttonCannel.name="buttonCannel"; button.buttonMode=true; buttonOk.buttonMode=true; buttonCannel.buttonMode=true; button.Move(rect.right-button.width,rect.bottom-button.height); buttonOk.Move(rect.x,rect.bottom); buttonCannel.Move(rect.x+60,rect.bottom); } else { addActionListener(); } } //拖动图形 private function startdragRect():void { if (checkRect(rect)) { pen.addEventListener(MouseEvent.MOUSE_DOWN,startDragHandler);//拖动监听 pen.buttonMode=true; } else { addActionListener(); } } //用于缩放矩形 private function startDragHandler(event:MouseEvent):void { point=new Point(this.target.mouseX-rect.x,this.target.mouseY-rect.y); target.addEventListener(MouseEvent.MOUSE_MOVE,DragingHandler); target.addEventListener(MouseEvent.MOUSE_UP,EndDragHandler); } private function DragingHandler(event:MouseEvent):void { if (point!=null) { rect=new Rectangle(this.target.mouseX - point.x,this.target.mouseY - point.y,rect.width,rect.height); DrawRect(pen,rect); button.Move(rect.right-button.width,rect.bottom-button.height); buttonOk.Move(rect.x,rect.bottom); buttonCannel.Move(rect.x+60,rect.bottom); event.updateAfterEvent(); } } private function EndDragHandler(event:MouseEvent):void { point=null; target.removeEventListener(MouseEvent.MOUSE_MOVE,this.DragingHandler); target.removeEventListener(MouseEvent.MOUSE_UP,this.EndDragHandler); } private function buttonDownHandler(event:MouseEvent):void { switch (event.target.name) { case "dragbutton" : target.addEventListener(MouseEvent.MOUSE_MOVE,ScaeHandler); target.addEventListener(MouseEvent.MOUSE_UP,EndScaleHandler); break; case "buttonOk" : this.dispatchEvent(new SelectEvent(SelectEvent.COMPLETE)); break; case "buttonCannel" : target.removeEventListener(MouseEvent.MOUSE_MOVE,DrawingHandler); this.dispatchEvent(new SelectEvent(SelectEvent.CANCEL)); trace("ww"); break; } } private function ScaeHandler(event:MouseEvent):void { rect=new Rectangle(rect.x,rect.y,this.target.mouseX - rect.x,this.target.mouseY - rect.y); button.Move(rect.right-button.width,rect.bottom-button.height); buttonOk.Move(rect.x,rect.bottom); buttonCannel.Move(rect.x+60,rect.bottom); DrawRect(pen,rect); event.updateAfterEvent(); } private function EndScaleHandler(event:MouseEvent):void { target.removeEventListener(MouseEvent.MOUSE_MOVE, ScaeHandler); target.removeEventListener(MouseEvent.MOUSE_UP, EndScaleHandler); } //裁剪返回一个位图数据 public function CutIamge(source:Bitmap):Bitmap { return super.getImage(source,rect); } //返回矩形 public function getRect2D():Rectangle { return rect; } //取消 public function Cancel():void { pen.graphics.clear(); rect=null; pen.removeEventListener(MouseEvent.MOUSE_DOWN, startDragHandler); buttonOk.removeEventListener(MouseEvent.MOUSE_DOWN, buttonDownHandler); button.removeEventListener(MouseEvent.MOUSE_DOWN, buttonDownHandler); buttonCannel.removeEventListener(MouseEvent.MOUSE_DOWN, buttonDownHandler); while (target.numChildren>2) { target.removeChildAt(target.numChildren-1); } } } }
制作UI:制作UI的时候,我们需要制作三个按钮也可以更加多,因为我只是实现了一个点。可以进行拖放的控制,因此这种设计会简化,然而对更加多的点支持则需要进行修改完善。
按钮的说明:
第一个按钮用于对矩形的缩放,
第二,第三分布的确定和取消的按钮。 用于交互是否裁剪
用于缩放的时候进行操作。
package org.summerTree.button { //该类为缩放的button 按钮 import flash.display.Sprite; public class SButton extends Sprite { public var LineColor:uint=0x0000ff;//线条颜色 public var FillColor:uint=0xff0000;//填充的颜色 public var FillAlpha:uint=1; public function SButton() { this.buttonMode=true; this.graphics.clear(); this.graphics.lineStyle(1,LineColor,1); this.graphics.beginFill(FillColor,FillAlpha); this.graphics.drawRect(0,0,20,8); this.graphics.endFill(); } public function Move(x:Number,y:Number):void { this.x=x; this.y=y; } } }
取消和确定按钮。
package org.summerTree.button { //该类为缩放的button 按钮 import flash.display.Sprite; import flash.display.Loader; import flash.display.Bitmap; import flash.events.*; import flash.net.URLRequest; public class ButtonBar extends Sprite { public function ButtonBar() { } public function clone():ButtonBar { return new ButtonBar(); } //添加按钮 public function addButton(path:String):void { var loader:Loader=new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete); loader.load(new URLRequest(path)); } private function onComplete(event:Event):void { var bitmap:Bitmap=event.currentTarget.content; addChild(bitmap); event.currentTarget.removeEventListener(Event.COMPLETE,onComplete); } public function Move(x:Number,y:Number):void { this.x=x; this.y=y; } } }
按钮路径
package org.summerTree.button { //按钮路径 public final class ButtonPath { public static const Btn_ok:String="org/summerTree/button/skin/ok.png"; public static const Btn_cannel:String="org/summerTree/button/skin/cannel.png" } }
自定义事件:用于裁剪的位图 自定义的事件
package org.summerTree.event { //裁剪事件 import flash.events.Event; public class SelectEvent extends Event { public static const COMPLETE:String="complete";//完成事件 public static const CANCEL:String="cancel";//取消事件 public function SelectEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false) { super(type,false,false); } override public function clone():Event { return new SelectEvent(SelectEvent.COMPLETE); } } }
基本用法:
首先先创建一个Selector 类,用于指定两参数,其中是一个容器,一个是stage 舞台。
在容器当中,我们创建了一个位图,这张位图可以是在库链接出来,也可以外部加载出来的
使用的方法很简单。
import org.summerTree.Selector; import org.summerTree.event.SelectEvent; var contain:MovieClip=new MovieClip(); addChild(contain) var bitmapdata:BitmapData=new Image(0,0); contain.addChild(new Bitmap(bitmapdata)); var myselect:Selector=new Selector(contain,stage); myselect.addActionListener(); myselect.addEventListener(SelectEvent.COMPLETE,cutImageHandler); myselect.addEventListener(SelectEvent.CANCEL,cancelHandler); function cancelHandler(event:SelectEvent):void { myselect.Cancel(); myselect.addActionListener(); } function cutImageHandler(event:SelectEvent):void { var bit:Bitmap=myselect.CutIamge(contain.getChildAt(0) as Bitmap); contain.removeChildAt(0); contain.addChildAt(bit,0); myselect.Cancel(); myselect.addActionListener(); }
下面可以下载来玩一下,看看效果如何。