Copy link to clipboard
Copied
I think a couple people asked about this problem but none of them seemed to get an answer so I am re-posting.
This is how blur filter and mask work in code
var blur:BlurFilter = new BlurFilter();
blur.blurX = 10;
blur.blurY = 10;
var mask:Bitmap = new Bitmap(...)
var shape:Shape = new Shape();
shape.graphics.beginFill(color, alpha);
shape.graphics.moveTo(100, 100);
shape.graphics.lineTo(...);
shape.graphics.endFill();
shape.filters = [blur]
shape.mask = mask;
bitmap.bitmapData.draw(shape);
But result is not what I want. Please see the below image:
Making another bitmap and copy pixels using the mask works but it makes whole applcation very slow.
How can I mask blur filter using a single draw?
The difference between the code I posted and what you have there is that you are applying the mask and the blur to the shape, whereas I applied the blur to the shape and the mask to a container the shape is inside. This is because for a given object the filters apply AFTER any masking, but you want the reverse. The only way to control the order that I know if is to create more layers.
In other words, change the last code you posted like this:
1. Create a container for the shape:
...var container:Sprit
Copy link to clipboard
Copied
Have you tried putting the shape inside a movieclip and apply the mask to the movieclip instead of the shape?
Copy link to clipboard
Copied
Thanks for asking. As far as I know, the "graphic" in shape behaviours exactly same with one in sprite or movieclip
Copy link to clipboard
Copied
Can you post the complete code with the mask and shape defined?
Copy link to clipboard
Copied
Here is my code:
public static function drawPolygon(bitmap:Bitmap, points:Array, color:uint, alpha:Number=1.0, filters:Array=null, mask:Bitmap=null):void
{
if(points == null || points.length < 3) {
return;
}
var shape:Shape = new Shape();
shape.graphics.beginFill(color, alpha);
shape.graphics.moveTo(points[0].x, points[0].y);
var i:int;
for(i=1;i<points.length;i++) {
shape.graphics.lineTo(points.x, points.y);
}
shape.graphics.endFill();
if(filters != null) {
shape.filters = filters;
}
if(mask != null) {
shape.cacheAsBitmap = true;
mask.cacheAsBitmap = true;
shape.mask = mask;
}
bitmap.bitmapData.draw(shape);
}
//create blur filter
var blur:BlurFilter = new BlurFilter();
blur.blurX = 10;
blur.blurY = 10;
//create mask
var mask:Bitmap = new Bitmap(new BitmapData(bitmap.width, bitmap.height));
Tools.fillWithOneColor(mask, 0x000000);
Tools.drawPolygon(mask, maskPoints, 0xffffff);
//draw blured and masked polygon
Tools.drawPolygon(bitmap, points, _color, _alpha/2, [blur], mask);
Please let me know if there is anything I sould change..
Copy link to clipboard
Copied
It`s not advisable to name your instances with reserved keywords, properties etc.
try
_shape.filters = [blur];
_shape.cacheAsBitmap = true;
_mask.cacheAsBitmap = true;
shape.mask = _mask;
Copy link to clipboard
Copied
Thanks for replying. but that does not work in my side unfortunately. Please take a look at my code
Copy link to clipboard
Copied
filters in Flash are somwhat unreliable when combined with masking.
Try to use a non native famework like greensock ( http://www.greensock.com/tweenmax/ )
and rewrite your blurfilter like this:
import com.greensock.*;
import com.greensock.easing.*;
TweenMax.to(shape, 0, {blurFilter:{blurX:10, blurY:10}});
Copy link to clipboard
Copied
Thanks! but It seems like I have to pay for the license to use greensock :S
Copy link to clipboard
Copied
Greensock filters are the same thing.
I'm a little unclear what you're trying to do here, and there's some code missing so I can't really play with it. Can you boil down a simple example? The following code creates the "what you want" image but I'm not sure it does it the way you want. Hope it helps!
-Aaron
// create a container
var container:Sprite = new Sprite();
addChild(container);
// draw a circle and put it in the container
var circle:Shape = new Shape();
var g:Graphics = circle.graphics;
g.beginFill(0xff0000);
g.drawCircle(100, 100, 75);
container.addChild(circle);
// draw a blocky mask
var block:Shape = new Shape();
g = block.graphics;
g.beginFill(0);
g.lineTo(100, 0);
g.lineTo(100, 100);
g.lineTo(200, 100);
g.lineTo(200, 200);
g.lineTo(0, 200);
addChild(block);
// apply the mask to the outer container
container.mask = block;
// apply the filter to the inner circle
circle.filters = [new BlurFilter(50, 50)];
// create a bitmap
var bitmap:Bitmap = new Bitmap(new BitmapData(200, 200, true));
bitmap.x = 200;
addChild(bitmap);
// draw that masked and blurred circle to the bitmap
bitmap.bitmapData.draw(container);
Copy link to clipboard
Copied
Thx for replying. Like you showed me, I tried with Shape as mask object indtead of bitmap. But it did not work either :S
Here is my code:
//create bitmap
var bitmap:Bitmap = new Bitmap(new BitmapData(400,400));
//create blur filter
var blur:BlurFilter = new BlurFilter(10, 10);
//create shape
var shape:Shape = new Shape();
shape.graphics.beginFill(0xff0000, 0.8);
shape.graphics.drawCircle(200,200,100);
shape.graphics.endFill();
shape.filters = [blur];
//create mask
var block:Shape = new Shape();
block.graphics.beginFill(0);
block.graphics.drawCircle(250,200,100);
block.graphics.endFill();
shape.cacheAsBitmap = true;
block.cacheAsBitmap = true;
shape.mask = block;
bitmap.bitmapData.draw(shape);
and this is the result:
any idea?
Copy link to clipboard
Copied
The difference between the code I posted and what you have there is that you are applying the mask and the blur to the shape, whereas I applied the blur to the shape and the mask to a container the shape is inside. This is because for a given object the filters apply AFTER any masking, but you want the reverse. The only way to control the order that I know if is to create more layers.
In other words, change the last code you posted like this:
1. Create a container for the shape:
var container:Sprite = new Sprite();
2. Add the shape to the container:
container.addChild(shape);
3. Apply the blur to the shape, and the mask to the container:
shape.filters = [blur];
container.mask = block;
3. Draw the container to the bitmap:
bitmap.bitmapData.draw(container);
That should produce the image you want.
-Aaron
Copy link to clipboard
Copied
It works! Thanks Aaron!!
Copy link to clipboard
Copied
Go back to the first response you received to see what it suggested.
Copy link to clipboard
Copied
Thanks Ned. I appreciate you as well. I could not understand what you suggested but now I can.