package laan.smart.bitmap
2{
3 import flash.display.BitmapData;
4 import flash.display.BitmapDataChannel;
5 import flash.filters.ColorMatrixFilter;
6 import flash.filters.ConvolutionFilter;
7 import flash.filters.DisplacementMapFilter;
8 import flash.filters.DisplacementMapFilterMode;
9 import flash.geom.Point;
10 import flash.geom.Rectangle;
11
12 /**
13 * 滤镜生成器
14 *
15 * <p>
16 * 用于生成黑白照、水彩、模糊、膨胀、挤压等滤镜。
17 * </p>
18 *
19 * <p>
20 * 部分代码源自rakuto:http://code.google.com/p/as3filters/
21 * </p>
22 *
23 * @author laan
24 * @createTime 2008.11
25 *
26 * @see http://www.laaan.cn
27 * @see http://code.google.com/p/as3filters/
28 *
29 */
30 public class FilterFactory
31 {
32 /**
33 * 水彩滤镜
34 *
35 * @param size 目标对象范围
36 * @param region 滤镜作用范围
37 * @param factor 接收一个0-1的Number数据,指定水彩化系数
38 *
39 * @return 返回一个<code>DisplacementMapFilter</code>滤镜
40 *
41 */
42 public static function aquarelleFilter(size:Rectangle, region:Rectangle = null, factor:Number = 0.5):DisplacementMapFilter {
43 if (!region) region = new Rectangle(0, 0, size.width, size.height);
44
45 if (factor > 1) factor = 1;
46 if (factor < 0) factor = 0;
47
48
49
50 var bd:BitmapData = new BitmapData(size.width, size.height, false, 0x000000);
51 var no:BitmapData = new BitmapData(size.width, size.height);
52 no.noise(factor * 10, 0, 255, BitmapDataChannel.RED);
53
54 bd.copyPixels(no, region, new Point(region.x, region.y));
55
56 var chanel:uint = BitmapDataChannel.RED;
57 var filter:DisplacementMapFilter = new DisplacementMapFilter(bd, new Point(0, 0), chanel, chanel, factor * 5, factor * 5);
58
59 return filter;
60 }
61
62 /**
63 * 模糊滤镜
64 *
65 * @param factor 接收一个0-1的Number数据,指定水彩化系数
66 *
67 * @return 返回一个<code>ConvolutionFilter</code>滤镜
68 *
69 */
70 public static function FuzzyFilter(factor:Number = 0.5):ConvolutionFilter {
71 if (factor > 1) factor = 1;
72 if (factor < 0) factor = 0;
73
74 factor *= 10;
75
76 var matrix:Array = [];
77 var i:uint = 0;
78 while(i++ < factor * factor) {
79 matrix.push(1);
80 }
81
82 var filter:ConvolutionFilter = new ConvolutionFilter(factor, factor, matrix, factor * factor);
83
84 return filter;
85 }
86
87 /**
88 * 灰度滤镜
89 *
90 *
91 * @return 返回一个<code>ColorMatrixFilter</code>滤镜
92 *
93 */
94 public static function grayFilter():ColorMatrixFilter {
95 var matrix:Array = [0, 1, 0, 0, 0,
96 0, 1, 0, 0, 0,
97 0, 1, 0, 0, 0,
98 0, 0, 0, 1, 0];
99
100 return new ColorMatrixFilter(matrix);
101 }
102
103 /**
104 * 浮雕滤镜
105 *
106 * @return 返回一个<code>ConvolutionFilter</code>滤镜
107 *
108 */
109 public static function reliefFilter():ConvolutionFilter {
110 var matrix:Array = [-2,-1,0,-1,1,1,0,1,2];
111
112 var filter:ConvolutionFilter = new ConvolutionFilter(3, 3, matrix, 1);
113 return filter;
114 }
115
116 /**
117 * 木雕滤镜
118 *
119 * @param factor 0-1
120 *
121 * @return 返回一组滤镜
122 *
123 */
124 public static function woodCarvingFilter(factor:Number = 0.5):Array {
125 if (factor > 1) factor = 1;
126 if (factor < 0) factor = 0;
127
128 factor *= 10;
129
130 var matrix:Array = [0, 1, 0, 0, -127,
131 0, 1, 0, 0, -127,
132 0, 1, 0, 0, -127,
133 0, 0, 0, 1, 0];
134
135 var matrix2:Array = [0, factor, 0, 0, 0,
136 0, factor, 0, 0, 0,
137 0, factor, 0, 0, 0,
138 0, 0, 0, 1, 0];
139
140 return [new ColorMatrixFilter(matrix), new ColorMatrixFilter(matrix2)];
141 }
142
143 /**
144 * 扭曲滤镜
145 *
146 * @param size
147 * @param region
148 * @param rotation
149 *
150 * @return
151 *
152 */
153 public static function twirlFilter(size:Rectangle, region:Rectangle=null, rotation:Number=0):DisplacementMapFilter {
154 if (!region) region = new Rectangle(0, 0, size.width, size.height);
155
156 rotation ||= Math.PI / 2;
157
158 var width:int = size.width;
159 var height:int = size.height;
160
161 var dbmd:BitmapData = new BitmapData(size.width, size.height, false, 0x8080);
162 var radius:Number = Math.min(region.width, region.height) / 2;
163 var centerX:int = region.x + region.width / 2;
164 var centerY:int = region.y + region.height / 2;
165
166 for(var y:int = 0; y < height; ++y) {
167 var ycoord:int = y - centerY;
168 for(var x:int = 0; x < width; ++x) {
169 var xcoord:int = x - centerX;
170 var dr:Number = radius - Math.sqrt(xcoord * xcoord + ycoord * ycoord);
171 if(dr > 0) {
172 var angle:Number = dr / radius * rotation;
173 var dx:Number = xcoord * Math.cos(angle) - ycoord * Math.sin(angle) - xcoord;
174 var dy:Number = xcoord * Math.sin(angle) + ycoord * Math.cos(angle) - ycoord;
175 var blue:int = 0x80 + Math.round(dx / width * 0xff);
176 var green:int = 0x80 + Math.round(dy / height * 0xff);
177 dbmd.setPixel(x, y, green << 8 | blue);
178 }
179 }
180 }
181 return new DisplacementMapFilter(dbmd,
182 new Point(0, 0),
183 BitmapDataChannel.BLUE,
184 BitmapDataChannel.GREEN,
185 width,
186 height,
187 DisplacementMapFilterMode.IGNORE);
188 }
189
190 /**
191 * 挤压滤镜
192 *
193 * @param size
194 * @param region
195 * @param amount
196 * @return
197 *
198 */
199 public static function squeezeFilter(size:Rectangle, region:Rectangle = null, factor:Number = 0.5):DisplacementMapFilter {
200 var width:int = size.width;
201 var height:int = size.height;
202
203 region ||= new Rectangle(0, 0, width, height);
204
205 var radius:Number = Math.min(region.width, region.height) / 2;
206 var centerX:int = region.x + region.width / 2;
207 var centerY:int = region.y + region.height / 2;
208 var dbmd:BitmapData = new BitmapData(width, height, false, 0x8080);
209
210 for(var y:int = 0; y < height; ++y) {
211 var ycoord:int = y - centerY;
212 for(var x:int = 0; x < width; ++x) {
213 var xcoord:int = x - centerX;
214 var d:Number = Math.sqrt(xcoord * xcoord + ycoord * ycoord);
215 if(d < radius) {
216 var t:Number = d == 0 ? 0 : Math.pow(Math.sin(Math.PI / 2 * d / radius), -factor);
217 var dx:Number = xcoord * (t - 1) / width;
218 var dy:Number = ycoord * (t - 1) / height;
219 var blue:int = 0x80 + dx * 0xff;
220 var green:int = 0x80 + dy * 0xff;
221 dbmd.setPixel(x, y, green << 8 | blue);
222 }
223 }
224 }
225
226 return new DisplacementMapFilter(dbmd,
227 new Point(0, 0),
228 BitmapDataChannel.BLUE,
229 BitmapDataChannel.GREEN,
230 width,
231 height,
232 DisplacementMapFilterMode.CLAMP);
233 }
234
235 /**
236 * 膨胀滤镜
237 *
238 * @param size
239 * @param region
240 * @param factor
241 *
242 * @return
243 *
244 */
245 public static function bulgeFilter(size:Rectangle, region:Rectangle = null, factor:Number = 0.5):DisplacementMapFilter {
246 return squeezeFilter(size, region, Math.min(-factor, -1));
247 }
248
249 /**
250 * 鱼眼滤镜
251 *
252 * @param size
253 * @param region
254 * @param factor
255 *
256 * @return
257 *
258 */
259 public static function fisheyeFilter(size:Rectangle, region:Rectangle = null, factor:Number = 0.8):DisplacementMapFilter {
260 var width:int = size.width;
261 var height:int = size.height;
262
263 region ||= new Rectangle(0, 0, width, height);
264
265 var dbmd:BitmapData = new BitmapData(width, height, false, 0x8080);
266
267 var centerX:int = region.x + region.width / 2;
268 var centerY:int = region.y + region.height / 2;
269
270 var radius:Number = Math.sqrt(region.width * region.width + region.height * region.height);
271
272 for(var y:int = 0; y < height; ++y) {
273 var ycoord:int = y - centerY;
274 for(var x:int = 0; x < width; ++x) {
275 var xcoord:int = x - centerX;
276 var d:Number = Math.sqrt(xcoord * xcoord + ycoord * ycoord);
277 if(d < radius) {
278 var t:Number = d == 0 ? 0 : Math.pow(Math.sin(Math.PI / 2 * d / radius), factor);
279 var dx:Number = xcoord * (t - 1) / width;
280 var dy:Number = ycoord * (t - 1) / height;
281 var blue:int = 0x80 + dx * 0xff;
282 var green:int = 0x80 + dy * 0xff;
283 dbmd.setPixel(x, y, green << 8 | blue);
284 }
285 }
286 }
287
288 return new DisplacementMapFilter(dbmd,
289 new Point(0, 0),
290 BitmapDataChannel.BLUE,
291 BitmapDataChannel.GREEN,
292 width,
293 height,
294 DisplacementMapFilterMode.CLAMP);
295 }
296 }
297}
=--------------------
源文:http://www.cnblogs.com/laan860102/archive/2009/06/25/1511003.html