my space:http://www.laaan.cn

图片滤镜demo

近一直在研究图片滤镜。呵呵,也是工作需要啊——搜狗输入法的大头贴四期将加入图片滤镜功能。死了很多脑细胞,不过收获还是蛮多。感谢rakuto

  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(00, 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, false0x000000);
 51            var no:BitmapData = new BitmapData(size.width, size.height);
 52            no.noise(factor * 100255, 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(00), 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 = [01000,
 96                                01000,
 97                                01000,
 98                                00010];
 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(33, 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 = [0100-127,
131                                0100-127,
132                                0100-127,
133                                00010];
134            
135            var matrix2:Array = [0, factor, 000,
136                                0, factor, 000,
137                                0, factor, 000,
138                                00010];
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(00, 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, false0x8080);
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(00),
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(00, 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, false0x8080);
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(00),
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(00, width, height);
264              
265            var dbmd:BitmapData = new BitmapData(width, height, false0x8080);
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(00),
290                                            BitmapDataChannel.BLUE,
291                                            BitmapDataChannel.GREEN,
292                                            width,
293                                            height,
294                                            DisplacementMapFilterMode.CLAMP);
295        }

296    }

297}

 

posted @ 2009-06-25 15:10  laan  阅读(3011)  评论(18编辑  收藏  举报
my space:http://www.laaan.cn