基于Flex的裁剪图片功能封装

基于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)、裁剪的大小(宽、高)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值