您的位置:首页 > 其它

基于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)、裁剪的大小(宽、高)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息