我一直试图找出一个使用Actionscript3执行位图裁剪的好策略。
例如:我有一张汽车的照片,我想单独从图像中裁剪出汽车,并将边缘羽毛化,使它们看起来不会锯齿状。
我是一个闪光菜刀,只用了几个星期。我已经尝试了几个选项,这是我提出的最后一个选项:我在舞台上放置了可以拖动的红点,这样你就可以勾勒出想要裁剪的对象,并且点是一个边界。 gradientFill用作位图的掩码。 (我使用径向渐变...所以结果远非我想要的,因为汽车不是椭圆形的。)
以下是结果图片。(忽略随机黄色虚线椭圆形)
package code{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.MouseEvent;
//import flash.display.Graphics;
import fl.controls.Button;
import code.CropDot;
import flash.display.MovieClip;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.geom.Matrix;
import flash.display.Shape;
//import fl.controls.RadioButton;
public class BitmapEdit extends Sprite{
public var maskee:MovieClip;
public var bitmap:Bitmap;
public var dots:Sprite;
public var fill:MovieClip;
public var numDots:int;
public var circ:Shape = new Shape();
////////////////////
public var mat:Matrix=new Matrix();
public var circRad:Number=50;
public var offsetX:int;
public var offsetY:int;
public function BitmapEdit(bmp:Bitmap){
trace("bitmapedit");
//MASK Stuff
//--------------
bitmap = new Bitmap(bmp.bitmapData);
maskee = new MovieClip();
maskee.addChild(bitmap);
fill = new MovieClip();
this.addChild(maskee);
this.addChild(fill);
maskee.mask = fill;
maskee.cacheAsBitmap = true;
fill.cacheAsBitmap = true;
// DOTS DOTS DOTS
//---------------
dots = new Sprite();
numDots = 12;
offsetX = 90;
offsetY = 90;
cX = dot0.x+offsetX;
cY = dot0.y+offsetY;
rangeX = [cX,cX];
rangeY = [cY,cY];
for(var i:int=0;i<numDots;i++){
this['dot'+i.toString()].x += offsetX;
this['dot'+i.toString()].y += offsetY;
//this['dot'+i.toString()].name = 'dot'+i.toString();
dots.addChild(this['dot'+i.toString()])
cX+=dotX;
cY+=dotY;
if(dotX<=rangeX[0])
rangeX[0]=dotX;
else if(dotX>rangeX[1])
rangeX[1]=dotX;
if(dotY<=rangeY[0])
rangeY[0]=dotY;
else if(dotY>rangeY[1])
rangeY[1]=dotY;
}
cdot.x = cX;
cdot.y = cY;
this.addChild(dots);
fill.graphics.lineStyle(3,0,1.0,true);
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
public var cX:Number;
public var cY:Number;
public var dotX:Number;
public var dotY:Number;
public var prevdotX:Number;
public var prevdotY:Number;
public var rangeX:Array;
public var rangeY:Array;
protected function enterFrameHandler(e:Event){
//draw lines between dots
this.setChildIndex(fill,this.numChildren-2);
this.setChildIndex(dots,this.numChildren-1);
fill.graphics.clear();
//-Draw Fill
var fW = rangeX[1]-rangeX[0];
var fH = rangeY[1]-rangeY[0];
mat.createGradientBox(fW, fH, 0, cX-fW/2, cY-fH/2);
//fill.graphics.beginFill(0,1);
//fill.graphics.beginBitmapFill(bitmap.bitmapData);
//mat = new Matrix();
//fill.graphics.beginFill(0,1);
fill.graphics.beginGradientFill(GradientType.RADIAL,[0x000000, 0x000000], [1, 0], [123,255], mat, SpreadMethod.PAD, "rgb", 0);
fill.graphics.moveTo(dot0.x, dot0.y);
cX = dot0.x;
cY = dot0.y;
prevdotX = dot0.x;
prevdotY = dot0.y;
rangeX = [cX,cX];
rangeY = [cY,cY];
for(var i:int=1; i<numDots; i++){
dotX = this['dot'+i.toString()].x;
dotY = this['dot'+i.toString()].y;
fill.graphics.lineTo( dotX, dotY);
cX+=dotX;
cY+=dotY;
if(dotX<=rangeX[0])
rangeX[0]=dotX;
else if(dotX>rangeX[1])
rangeX[1]=dotX;
if(dotY<=rangeY[0])
rangeY[0]=dotY;
else if(dotY>rangeY[1])
rangeY[1]=dotY;
}
cX/=numDots;
cY/=numDots;
//trace("ctr:"+cX+","+cY);
cdot.x = cX;
cdot.y = cY;
fill.graphics.lineTo(dot0.x,dot0.y);
// */
//EndFill
fill.graphics.endFill();
}
function toRad(a:Number):Number {
return a*Math.PI/180;
}
}
}
问题
1)我怎样才能淡化红点所勾勒出的这种定制形状填充物的边缘?
2)我想在裁剪后将图像保存到文件中。使用BitmapFill或GradientFill作为掩码,这样做的策略会更好(如果两者都可以的话)?
3)我可能正在使用这种策略稍后裁剪人脸..任何人都知道as3的任何良好的面部检测API? (也是边缘检测API)
非常感谢大家:)
答案 0 :(得分:3)
1)我一直在使用的是创建一个矩形(根据我的需要)但是多边形应该可以工作...... 基本上我创建一个图形应用模糊过滤器并将其用作蒙版。 (而不是使用渐变)
2)查看hype framework,其中有一个类允许您导出图像(tif,png),但还有其他选择。基本上,如果您创建位图并使用绘图功能,则可以使用位图进行导出,
3)你应该看看as3中的haar级联这里有一个链接,其中有很多信息,现在它在as3中相当缓慢,但是谁知道,也许新的molehills api可能会很快改变。 http://web.elctech.com/2009/04/02/using-haar-cascades-and-opencv-in-as3/