Flex提供了两种方法截图,一个是BitmapData的draw 方法,另一个是ImageSnapshot 提供的captureImage和captureBitmapData静态方法,其实这两种方法没有什么本质的区别,因为ImageSnapshot提供的这些方法本质上也是通过BitmapData的draw方法来截图的。
如果非要要说有什么区别的话,那就是ImageSnapShot提供的这些方法你没有办法设置要截取多大,它会自动根据你传入的对象来算长宽。而BitmapData你可以再创建的时候指定长宽,那样你就可以截图想要的长宽了。
下面的例子是我做的一些测试代码,仅供参考。
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:Vgroup="com.view.Vgroup.*"> <fx:Declarations> <fx:XMLList id="employees"> <employee> <name>Christina Coenraets</name> <phone>555-219-2270</phone> <email>ccoenraets@fictitious.com</email> <active>true</active> </employee> <employee> <name>Joanne Wall</name> <phone>555-219-2012</phone> <email>jwall@fictitious.com</email> <active>true</active> </employee> <employee> <name>Maurice Smith</name> <phone>555-219-2012</phone> <email>maurice@fictitious.com</email> <active>false</active> </employee> <employee> <name>Mary Jones</name> <phone>555-219-2000</phone> <email>mjones@fictitious.com</email> <active>true</active> </employee> </fx:XMLList> </fx:Declarations> <fx:Script> <![CDATA[ import mx.controls.Image; import mx.core.IUIComponent; import mx.core.UIComponent; import mx.graphics.ImageSnapshot; import mx.graphics.codec.PNGEncoder; import spark.components.Label; import spark.filters.GlowFilter; [Embed(source='column_cone_1.png')] private var mark:Class; private function captureClickHandler(event:MouseEvent):void { var imageSnap:ImageSnapshot = ImageSnapshot.captureImage(dg); var imageByteArray:ByteArray = imageSnap.data as ByteArray; var loader:Loader = new Loader(); loader.loadBytes(imageByteArray); var ui:UIComponent = new UIComponent(); ui.addChild(loader); this.addElement(ui); } private function captureBitmapDataClickHandler(event:MouseEvent):void { var imageBitMapData:BitmapData=ImageSnapshot.captureBitmapData(dg); var pic:Bitmap= new mark(); var matrix:Matrix = new Matrix() matrix.translate(40,40); imageBitMapData.draw(pic,matrix);// 添加图片水印效果 addImage(imageBitMapData); } private function waterMarkClickHandler(event:MouseEvent):BitmapData { var imageBitMapData:BitmapData=ImageSnapshot.captureBitmapData(dg); var matrix:Matrix = new Matrix() matrix.translate(40,40); imageBitMapData.draw(waterLabel,matrix);// 添加文字水印效果 addImage(imageBitMapData); return imageBitMapData; } private function drawClickHandler(event:MouseEvent):void { var bitmapData:BitmapData = new BitmapData(testV.width,350); /*用bitmapData操作抓图,你的首先预设它的width,height。 clipAndEnableScrolling 为false时,group里面的内容会全部显示出来,不管group的实际长宽。 这个时候去抓图,可以把全部的内容抓到。如果为ture,group里面的内容超出group的显示区域的会被隐藏, 所以就只能抓到显示区域的内容了。 当然,如果你加了scroller,不管用bitmapdata还是ImageSnapshot,都只能抓到显示区域的内容了。 */ bitmapData.draw(testV,new Matrix()); addImage(bitmapData); var label:Label = new Label(); label.text = "adfasdf"; this.addElement(label); } private function captureInClipClickHandler(event:MouseEvent):void { var imageSnap:ImageSnapshot = ImageSnapshot.captureImage(testV); /*用ImageSnapshot抓图,它不会设置长宽,所以就只能抓到显示对象的实际长宽里面的内容了 */ var imageByteArray:ByteArray = imageSnap.data as ByteArray; var loader:Loader = new Loader(); loader.loadBytes(imageByteArray); var ui:UIComponent = new UIComponent(); ui.addChild(loader); this.addElement(ui); } private function saveClickHandler(event:MouseEvent):void { var imageBitMapData:BitmapData= waterMarkClickHandler(event); var file:FileReference = new FileReference(); var date:Date = new Date(); var jpgEncoder:PNGEncoder = new PNGEncoder(); var ba:ByteArray = jpgEncoder.encode(imageBitMapData); file.save(ba, date.getTime().toString() + ".jpg"); } private function addImage(mapData:BitmapData):void { var map:Bitmap = new Bitmap(); map.bitmapData = mapData; var img:Image = new Image(); img.source = map; this.addElement(img); } ]]> </fx:Script> <s:layout> <s:VerticalLayout/> </s:layout> <s:Label id="waterLabel" text="KENNY WATERMARK EXAMPLE" filters="{[new GlowFilter(0x333333, 1, 2, 2, 3)]}" visible="false" includeInLayout="false"/> <s:HGroup> <s:Button label="captureImage" click="captureClickHandler(event)"/> <s:Button label="captureBitmapData" click="captureBitmapDataClickHandler(event)"/> <s:Button label="waterMarkForCharactors" click="waterMarkClickHandler(event)"/> <s:Button label="draw" click="drawClickHandler(event)"/> <s:Button label="captureImageWithClipAndEnableScrolling" click="captureInClipClickHandler(event)"/> <s:Button label="SaveASPicture" click="saveClickHandler(event)"/> </s:HGroup> <s:HGroup> <mx:DataGrid id="dg" width="100%" height="100%" rowCount="5" dataProvider="{employees}"> <mx:columns> <mx:DataGridColumn dataField="name" headerText="Name"/> <mx:DataGridColumn dataField="phone" headerText="Phone"/> <mx:DataGridColumn dataField="email" headerText="Email"/> </mx:columns> </mx:DataGrid> <!--<s:Scroller>//可以自己加上Scroller试试--> <s:VGroup height="150" clipAndEnableScrolling="false" id="testV"> <s:Button height="50" label="test"/> <s:Button height="50" label="test1"/> <s:Button height="50" label="test2"/> <s:Button height="50" label="test3"/> <s:Button height="50" label="test4"/> </s:VGroup> <!--</s:Scroller>--> </s:HGroup> </s:Application>
这里没有涉及到抓图的高级应用和安全问题,有空会再写一些这方面的测试。