最近一直在研究图片滤镜。呵呵,也是工作需要啊——搜狗输入法的大头贴四期将加入图片滤镜功能。死了很多脑细胞,不过收获还是蛮多。
1package 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
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