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

2



3

4

5

6

7

8

9

10

11

12


13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31



32


33

34

35

36

37

38

39

40

41

42



43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62


63

64

65

66

67

68

69

70



71

72

73

74

75

76

77

78



79

80

81

82

83

84

85

86

87


88

89

90

91

92

93

94



95

96

97

98

99

100

101

102

103


104

105

106

107

108

109



110

111

112

113

114

115

116


117

118

119

120

121

122

123

124



125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143


144

145

146

147

148

149

150

151

152

153



154

155

156

157

158

159

160

161

162

163

164

165

166



167

168



169

170

171



172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190


191

192

193

194

195

196

197

198

199



200

201

202

203

204

205

206

207

208

209

210



211

212



213

214

215



216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235


236

237

238

239

240

241

242

243

244

245



246

247

248

249


250

251

252

253

254

255

256

257

258

259



260

261

262

263

264

265

266

267

268

269

270

271

272



273

274



275

276

277



278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297
