基于Flex的裁剪图片功能封装
2016-03-14 11:03
288 查看
基于Flex的裁剪图片功能封装
1、前言
由于工作原因,不得不接触flash的编程。就本身而言,以前没有编写flash的底子,编程技能也是处于初学者阶段。有许多不规范的地方,还请大家多多指教作为在网页上对于图片的一些操作,明显的js与html5更具有一些优势。js中的资源更加的丰富,html5更加的简洁方便。但是由于项目对于浏览器兼容的需要,所以只能选择flash进行编写这样的一个插件。
该插件用于对单张图片的一些操作,包括:对图片的缩放、拖动、涂抹、旋转、裁剪与上传(保存)。在其他功能上在网上都可以找到丰富的资源,涂抹的功能也可以通过画板一类的插件进行扩展而来。裁剪虽然也有些许功能,但是总是不尽人意,所以在完成一个初始版本之后,现在进行裁剪功能的代码重构,将其封装起来,方便使用。也对之前的工作进行一次总结。
2、代码
package cutImgFun { import flash.display.Bitmap; import flash.display.BitmapData; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import flash.utils.ByteArray; import mx.core.UIComponent; import mx.graphics.codec.PNGEncoder; import spark.components.Image; /** * 目前原始流程: * 1、读取源图片,原始矩阵与剪切信息。 * 2、源图片原始化,变为原图片 * 3、根据缩放比例进行裁剪。 * **/ public class CutImg { //裁剪参数:裁剪的位置与长宽---为相对于原图片的位置 private var cutX:Number;//裁剪位置的横坐标, private var cutY:Number;//裁剪位置的纵坐标 private var cutHeight:Number;//裁剪框的高度 private var cutWidth:Number;//裁剪框的宽度 //原图片参数:图片源文件,位置与长宽 private var sourceImg:Image;//需要进行剪切的原图片 private var sourceImgX:Number;//原图片的横坐标位置 private var sourceImgY:Number;//原图片的纵坐标位置 private var sourceImgHeight:Number;//原图片的高度 private var sourceImgWidth:Number;//原图片的宽度 //原图片的矩阵 private var sourceImgMatrix:Matrix;//原图片的矩阵,如果想获取缩放前图片的剪切,请使用初始的矩阵,不要使用当前矩阵 //原图片的初始矩阵 private var sourceImgPreMatrix:Matrix; //剪切过程中使用的矩阵 private var ImgMatrix:Matrix; // public function CutImg(source:Image,sourceImgMatrix:Matrix,sourceX:Number,sourceY:Number,sourceW:Number,sourceH:Number,cutX:Number,cutY:Number,cutW:Number,cutH:Number) // { // this.sourceImg=source; // this.sourceImgX=sourceX; // this.sourceImgY=sourceY; // this.sourceImgWidth=sourceW; // this.sourceImgHeight=sourceH; // // this.sourceImgMatrix=sourceImgMatrix; // // this.cutX=cutX; // this.cutY=cutY; // this.cutWidth=cutW; // this.cutHeight=cutH; // } /** * 构造函数,在原始图片基础上进行剪切,不包括缩放。 * * */ public function CutImg(source:Image,sourceImgPreMatrix:Matrix,cutX:Number,cutY:Number,cutW:Number,cutH:Number) { this.sourceImgMatrix=source.transform.matrix;//保存当前矩阵 this.sourceImgPreMatrix=sourceImgPreMatrix;//转换为初始矩阵 source.transform.matrix=sourceImgPreMatrix;//还原图片 //缩放比例 var ratio:Number=sourceImgPreMatrix.a/sourceImgMatrix.a trace(ratio); //trace(sourceImgMatrix.a); this.ImgMatrix=sourceImgPreMatrix;//剪切的时候使用原矩阵,在原始大小上进行裁剪 //整数化宽高,防止小数宽高对图片造成的变形 var width:int=source.width; source.width=width; var height:int=source.height; source.height=height; this.sourceImg=source; this.sourceImgX=source.x; this.sourceImgY=source.y; this.sourceImgWidth=source.width; this.sourceImgHeight=source.height; this.cutX=cutX*ratio; this.cutY=cutY*ratio; this.cutWidth=cutW*ratio; this.cutHeight=cutH*ratio; } /** * 获取最终得到的图片对象 **/ public function getCutImg():Image { //最终获取的图片 var finalImg:Image=new Image(); //设置最终图片的属性 finalImg.width=this.cutWidth; finalImg.height=this.cutHeight; finalImg.source=new PNGEncoder().encode(this.getCutImgBitMapData()); return finalImg; } /** * 利用targetImg显示剪切后的图片 **/ public function setCutImgToTarget(targetImg:Image):void { //设置最终图片的属性 targetImg.width=this.sourceImgWidth;//this.cutWidth; targetImg.height=this.sourceImgHeight;//this.cutHeight; targetImg.source=new PNGEncoder().encode(this.getCutImgBitMapData()); } /** * 获取剪切的BitmapData数据 **/ private function getCutImgBitMapData():BitmapData { //将原图片转为数组 var byteArr:ByteArray =ImageToByteArray(sourceImg); //将数组转为bitmap var bitmap:Bitmap = ByteArrayToBitmap(byteArr); //创建剪切容器 var bitmapData:BitmapData = new BitmapData(this.cutWidth,this.cutHeight); //通过原图片的bitMap进行剪切并保存到这个容器中。 bitmapData.copyPixels(bitmap.bitmapData,new Rectangle(this.cutX,this.cutY,this.cutWidth,this.cutHeight),new Point(0,0)); // var bitmapData:BitmapData = new BitmapData(this.sourceImgWidth,this.sourceImgHeight); // bitmapData=bitmap.bitmapData; return bitmapData; } /** * 将单张图片转为ByteArray **/ private function ImageToByteArray(source:Image):ByteArray { //获取目标图片的bitmapData类型数据 //var sourceBitmapData:BitmapData=source.bitmapData; var sourceBitmapData:BitmapData =new BitmapData(this.sourceImgWidth,this.sourceImgHeight); sourceBitmapData.draw(source); //获取目标图片的位置与大小 var sourceRect:Rectangle=new Rectangle(0,0,this.sourceImgWidth,this.sourceImgHeight); //通过以上获取的两个数据得到目标图片的ByteArray类型数据 var sourceByteArray:ByteArray=sourceBitmapData.getPixels(sourceRect); //将高与宽写入 // sourceByteArray.writeShort(this.sourceImgWidth); // sourceByteArray.writeShort(this.sourceImgHeight); return sourceByteArray; } /** * 将ByteArray转为bitMap **/ private function ByteArrayToBitmap(byteArr:ByteArray):Bitmap{ //将写入的宽与高读取出来 // byteArr.position = byteArr.length -2; // var height:int = byteArr.readShort(); //imgHeightAuto;// // byteArr.position = byteArr.length -4; // var width:int = byteArr.readShort(); //imgWidthAuto;// var bitmapData:BitmapData = new BitmapData(this.sourceImgWidth,this.sourceImgHeight); //由于循环遍历图片是需要int值进行遍历的,而长度有可能是小数,如果不进行处理,则会造成数据遍历溢出,所以在这里缩小范围来达到效果,但是会造成数据的丢失。 var width:int=this.sourceImgWidth; var height:int=this.sourceImgHeight; trace("width"+this.sourceImgWidth+"-"+width+"--height:"+this.sourceImgHeight+"-"+height); byteArr.position = 0; for(var i:int = 0;i<this.sourceImgHeight;i++){ for(var j:int = 0;j<this.sourceImgWidth;j++){ //防止数组溢造成程序崩溃 if(byteArr.position<byteArr.length) bitmapData.setPixel(j,i,byteArr.readUnsignedInt()); } } var bitMap:Bitmap = new Bitmap(bitmapData); return bitMap; } /** * 清除冗余,在初始化的时候,设置剪切框在图片以内 **/ public function cleanEdge():void { //冗余状况 if(this.cutX+this.cutWidth<0)//左侧出界--相对位置 { cutRangeDefault(); } else if(this.cutX>this.sourceImgWidth)//右侧出界 { cutRangeDefault(); } else if(this.cutY+this.cutHeight<0)//上侧出界 { cutRangeDefault(); } else if(this.cutY>this.sourceImgHeight)//下侧出界 { cutRangeDefault(); } else//存在交叉的情况 { //获取交叉区域的左上角 var acrossLeftTopX:Number=maxNum(0,this.cutX); var acrossLeftTopY:Number=maxNum(0,this.cutY); //获取交叉区域的右下角 var acrossRightBottX:Number=minNum(this.sourceImgWidth,this.cutX+this.cutWidth); var acrossRightBottY:Number=minNum(this.sourceImgHeight,this.cutY+this.cutHeight); //重设剪切框--不再讨论正常情况,直接进行重设 this.cutX=acrossLeftTopX; this.cutY=acrossLeftTopY; this.cutWidth=acrossRightBottX-acrossLeftTopX; this.cutHeight=acrossRightBottY-acrossLeftTopY; } } /** * 返回两个数中的较大值 * */ public function maxNum(numA:Number,numB:Number):Number { if(numA>numB) { return numA; } else { return numB; } } /** * 返回两个数中的较小值 * */ public function minNum(numA:Number,numB:Number):Number { if(numA>numB) { return numB; } else { return numA; } } /** * 设置默认剪切范围,为原图大小。 * */ private function cutRangeDefault():void { this.cutX=0; this.cutY=0; this.cutWidth=this.sourceImgWidth; this.cutHeight=this.sourceImgHeight; } /************************************自定义******************************************************************/ /** * 利用targetImg显示剪切后的图片--自定义:添加涂抹板。 **/ public function setCutImgToTargetWithBoard(targetImg:Image,board:UIComponent):void { //设置最终图片的属性 targetImg.width=this.cutWidth; targetImg.height=this.cutHeight; targetImg.source=new PNGEncoder().encode(this.getCutImgBitMapDataWithBoard(board)); } /** * 获取剪切的BitmapData数据 **/ private function getCutImgBitMapDataWithBoard(board:UIComponent):BitmapData { //将原图片转为数组 var byteArr:ByteArray =BitmapDataToByteArrayForCut(board,sourceImg); //将数组转为bitmap var bitmap:Bitmap = ByteArrayToBitmap(byteArr); //创建剪切容器 var bitmapData:BitmapData = new BitmapData(this.cutWidth,this.cutHeight); //通过原图片的bitMap进行剪切并保存到这个容器中。 bitmapData.copyPixels(bitmap.bitmapData,new Rectangle(this.cutX,this.cutY,this.cutWidth,this.cutHeight),new Point(0,0)); // var bitmapData:BitmapData = new BitmapData(this.sourceImgWidth,this.sourceImgHeight); // bitmapData=bitmap.bitmapData; return bitmapData; } /** * 添加涂抹遮罩需要混合的时候 **/ private function BitmapDataToByteArrayForCut(target : UIComponent,source:Image):ByteArray { //混合画板与原图片 var bitmapData:BitmapData = UIComponentToBitmapData(target,source); /** * 裁剪修改************************************************************************************* */ var byteArr:ByteArray = bitmapData.getPixels(new Rectangle(0,0,this.sourceImgWidth,this.sourceImgHeight));//width,height)); return byteArr; } /** * 将可视的UIComponent组件转换为图片 **/ private function UIComponentToBitmapData(target : UIComponent,source:Image):BitmapData { var bitmapData:BitmapData =new BitmapData(this.sourceImgWidth,this.sourceImgWidth); //var targetMatrix:Matrix=this; //source.transform.matrix=this.ImgMatrix; bitmapData.draw(source);//保存原图像--未添加矩阵,因为添加之后会遭成偏移 bitmapData.draw(target);//添加涂抹效果 return bitmapData; } } }
3、代码使用方式
//新建一个裁剪对象 var cutImgFun1:CutImg = new CutImg(imgCase,imgMatrixDefault,cutBox.x,cutBox.y,cutBox.boxWidth,cutBox.boxHeight); //清除裁剪框与原图片间的空白 cutImgFun1.cleanEdge(); //将裁剪的结果传递给imgCase的图片对象。 cutImgFun1.setCutImgToTarget(imgCase);
初始化需要传递的值为需要裁剪的源图片、源图片的原始矩阵(裁剪后得到的为未进行缩放的图片)、裁剪的位置(x、y)、裁剪的大小(宽、高)。
相关文章推荐
- 按右键另存图片只能存BMP
- photoshop去除图片上的水印
- Flex 隐藏组件的属性
- Flex 如何得到itemRenderer里面的内容
- Flex字符串比较 还有Flex字符串操作
- Flex 透明效果,位于页面最底层
- Flex 非常实用的学习资料整理
- flex 控件的重要属性
- flex PopUpManager使用说明
- Flex clipContent 编程注意
- Flex 获得png透明截图的问题和解决方法
- FLEX TitleWindow之间数据传输的示例
- 在flex中执行一个javascript方法的简单方式
- Flex CategoryAxis 字体样式修改
- Flex结合JavaScript读取本地路径的方法
- Flex Namespace的用法
- Flex 性能优化常用手法总结
- flex 安全沙箱问题备忘
- Flex程序开发心得小结
- Flex Flash的关系分析