图片滤镜demo
最近一直在研究图片滤镜。呵呵,也是工作需要啊——搜狗输入法的大头贴四期将加入图片滤镜功能。死了很多脑细胞,不过收获还是蛮多。感谢rakuto
1
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
}
package laan.smart.bitmap2
{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 laan24
* @createTime 2008.1125
* 26
* @see http://www.laaan.cn27
* @see http://code.google.com/p/as3filters/28
* 29
*/ 30
public class FilterFactory31
{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-1120
* 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 size147
* @param region148
* @param rotation149
* 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 size194
* @param region195
* @param amount196
* @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 size239
* @param region240
* @param factor241
* 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 size253
* @param region254
* @param factor255
* 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
}


浙公网安备 33010602011771号