diff options
| author | Scott Ostler <sostler@deathmachine.local> | 2010-04-02 17:06:57 -0400 |
|---|---|---|
| committer | Scott Ostler <sostler@deathmachine.local> | 2010-04-02 17:06:57 -0400 |
| commit | 0447dc0cbea30537eeb55604cad19e265d305585 (patch) | |
| tree | 9b9f78666824b0daa102d26be4c93e24195e79ad | |
| parent | bd3925a4a19dd3b2c65abad579887b108d8f8546 (diff) | |
| parent | aa3165c303d8feb2a34329539c67bd71863c9eb4 (diff) | |
Resolved PROD merge
| -rwxr-xr-x | src/site.clj | 4 | ||||
| -rw-r--r-- | static/ako.gif | bin | 0 -> 780 bytes | |||
| -rw-r--r-- | static/beingpostednow.png | bin | 0 -> 21890 bytes | |||
| -rw-r--r-- | static/duh.gif | bin | 0 -> 1663 bytes | |||
| -rwxr-xr-x | static/dump.css | 10 | ||||
| -rw-r--r-- | static/dumpnewuser.css | 10 | ||||
| -rw-r--r-- | static/dumppreview.gif | bin | 0 -> 64609 bytes | |||
| -rw-r--r-- | static/dumppreview.png | bin | 0 -> 33629 bytes | |||
| -rw-r--r-- | static/hugescreen.png | bin | 0 -> 35913 bytes | |||
| -rw-r--r-- | static/ieburnbtn.gif | bin | 0 -> 2291 bytes | |||
| -rw-r--r-- | static/imageboard.png | bin | 22787 -> 21716 bytes | |||
| -rwxr-xr-x | static/index.html | 342 | ||||
| -rwxr-xr-x | static/js/pichat.js | 6 | ||||
| -rwxr-xr-x | static/js/register.js | 74 | ||||
| -rw-r--r-- | static/posthere.png | bin | 21289 -> 19883 bytes | |||
| -rw-r--r-- | static/readyjoin.png | bin | 14427 -> 14426 bytes | |||
| -rw-r--r-- | static/register.html | 14 | ||||
| -rwxr-xr-x | static/search/browser.css | 545 | ||||
| -rwxr-xr-x | static/search/browser.html | 19 | ||||
| -rw-r--r-- | static/trash/20bar.png (renamed from static/20bar.png) | bin | 3786 -> 3786 bytes | |||
| -rw-r--r-- | static/trash/20bar2.png (renamed from static/20bar2.png) | bin | 3786 -> 3786 bytes | |||
| -rw-r--r-- | static/trash/20bar3.png (renamed from static/20bar3.png) | bin | 2852 -> 2852 bytes | |||
| -rw-r--r-- | static/trash/20bar4.png (renamed from static/20bar4.png) | bin | 2864 -> 2864 bytes | |||
| -rw-r--r-- | static/trash/20bar5.png (renamed from static/20bar5.png) | bin | 2653 -> 2653 bytes | |||
| -rw-r--r-- | static/trash/20bar6.png (renamed from static/20bar6.png) | bin | 1021 -> 1021 bytes | |||
| -rwxr-xr-x | static/trash/background13.gif (renamed from static/background13.gif) | bin | 100 -> 100 bytes | |||
| -rwxr-xr-x | static/trash/background4.gif (renamed from static/background4.gif) | bin | 92 -> 92 bytes | |||
| -rw-r--r-- | static/trash/baygrad.png (renamed from static/baygrad.png) | bin | 4096 -> 4096 bytes | |||
| -rwxr-xr-x | static/trash/bg-random.gif (renamed from static/bg-random.gif) | bin | 43 -> 43 bytes | |||
| -rwxr-xr-x | static/trash/bg4.png (renamed from static/bg4.png) | bin | 5469 -> 5469 bytes | |||
| -rwxr-xr-x | static/trash/bg55.png (renamed from static/bg55.png) | bin | 1043 -> 1043 bytes | |||
| -rwxr-xr-x | static/trash/bgb.png (renamed from static/bgb.png) | bin | 1993 -> 1993 bytes | |||
| -rwxr-xr-x | static/trash/bgpat.gif (renamed from static/bgpat.gif) | bin | 329 -> 329 bytes | |||
| -rwxr-xr-x | static/trash/bgto.gif (renamed from static/bgto.gif) | bin | 160 -> 160 bytes | |||
| -rwxr-xr-x | static/trash/blink.gif (renamed from static/blink.gif) | bin | 17510 -> 17510 bytes | |||
| -rwxr-xr-x | static/trash/bluego.png (renamed from static/bluego.png) | bin | 6888 -> 6888 bytes | |||
| -rwxr-xr-x | static/trash/bottoml.png (renamed from static/bottoml.png) | bin | 660 -> 660 bytes | |||
| -rwxr-xr-x | static/trash/bottomr.png (renamed from static/bottomr.png) | bin | 649 -> 649 bytes | |||
| -rwxr-xr-x | static/trash/britglobe2.gif (renamed from static/britglobe2.gif) | bin | 93378 -> 93378 bytes | |||
| -rwxr-xr-x | static/trash/brokenlink.gif (renamed from static/brokenlink.gif) | bin | 38861 -> 38861 bytes | |||
| -rwxr-xr-x | static/trash/bubley.png (renamed from static/bubley.png) | bin | 17233 -> 17233 bytes | |||
| -rwxr-xr-x | static/trash/cat.jpeg (renamed from static/cat.jpeg) | bin | 2666 -> 2666 bytes | |||
| -rwxr-xr-x | static/trash/cloudbg.png (renamed from static/cloudbg.png) | bin | 8386 -> 8386 bytes | |||
| -rwxr-xr-x | static/trash/cloudbg1.png (renamed from static/cloudbg1.png) | bin | 8386 -> 8386 bytes | |||
| -rwxr-xr-x | static/trash/cloudbg2.png (renamed from static/cloudbg2.png) | bin | 8221 -> 8221 bytes | |||
| -rwxr-xr-x | static/trash/d.png (renamed from static/d.png) | bin | 2073 -> 2073 bytes | |||
| -rwxr-xr-x | static/trash/d3d1.gif (renamed from static/d3d1.gif) | bin | 16122 -> 16122 bytes | |||
| -rwxr-xr-x | static/trash/dblue.png (renamed from static/dblue.png) | bin | 4141 -> 4141 bytes | |||
| -rwxr-xr-x | static/trash/dddump.png (renamed from static/dddump.png) | bin | 3066 -> 3066 bytes | |||
| -rwxr-xr-x | static/trash/dddump2.png (renamed from static/dddump2.png) | bin | 2877 -> 2877 bytes | |||
| -rwxr-xr-x | static/trash/dfm.png (renamed from static/dfm.png) | bin | 4759 -> 4759 bytes | |||
| -rwxr-xr-x | static/trash/dumgradbub2.png (renamed from static/dumgradbub2.png) | bin | 6673 -> 6673 bytes | |||
| -rwxr-xr-x | static/trash/dump.gif (renamed from static/dump.gif) | bin | 4026 -> 4026 bytes | |||
| -rwxr-xr-x | static/trash/dumpbgword.gif (renamed from static/dumpbgword.gif) | bin | 180569 -> 180569 bytes | |||
| -rwxr-xr-x | static/trash/dumpbub.png (renamed from static/dumpbub.png) | bin | 5714 -> 5714 bytes | |||
| -rwxr-xr-x | static/trash/dumpd.gif (renamed from static/dumpd.gif) | bin | 17785 -> 17785 bytes | |||
| -rwxr-xr-x | static/trash/dumpd.png (renamed from static/dumpd.png) | bin | 33510 -> 33510 bytes | |||
| -rwxr-xr-x | static/trash/dumpl2.png (renamed from static/dumpl2.png) | bin | 6088 -> 6088 bytes | |||
| -rwxr-xr-x | static/trash/favicon2.ico (renamed from static/favicon2.ico) | bin | 1406 -> 1406 bytes | |||
| -rwxr-xr-x | static/trash/favicon6.ico (renamed from static/favicon6.ico) | bin | 1406 -> 1406 bytes | |||
| -rwxr-xr-x | static/trash/favicon7.ico (renamed from static/favicon7.ico) | bin | 1406 -> 1406 bytes | |||
| -rwxr-xr-x | static/trash/footer.png (renamed from static/footer.png) | bin | 243 -> 243 bytes | |||
| -rwxr-xr-x | static/trash/footer1.png (renamed from static/footer1.png) | bin | 190 -> 190 bytes | |||
| -rwxr-xr-x | static/trash/forealz.gif (renamed from static/forealz.gif) | bin | 4985 -> 4985 bytes | |||
| -rwxr-xr-x | static/trash/fuckit.gif (renamed from static/fuckit.gif) | bin | 37413 -> 37413 bytes | |||
| -rwxr-xr-x | static/trash/gaga.gif (renamed from static/gaga.gif) | bin | 52895 -> 52895 bytes | |||
| -rwxr-xr-x | static/trash/getstarted.gif (renamed from static/getstarted.gif) | bin | 6297 -> 6297 bytes | |||
| -rwxr-xr-x | static/trash/getstarted.html (renamed from static/getstarted.html) | 0 | ||||
| -rw-r--r-- | static/trash/headerbg.png (renamed from static/headerbg.png) | bin | 287 -> 287 bytes | |||
| -rw-r--r-- | static/trash/headerbg1.png (renamed from static/headerbg1.png) | bin | 287 -> 287 bytes | |||
| -rw-r--r-- | static/trash/headerbg2.png (renamed from static/headerbg2.png) | bin | 330 -> 330 bytes | |||
| -rw-r--r-- | static/trash/headerbg3.png (renamed from static/headerbg3.png) | bin | 329 -> 329 bytes | |||
| -rwxr-xr-x | static/trash/index5.html (renamed from static/index5.html) | 0 | ||||
| -rwxr-xr-x | static/trash/lil-wayne.jpg (renamed from static/lil-wayne.jpg) | bin | 104782 -> 104782 bytes | |||
| -rwxr-xr-x | static/trash/lillogo.png (renamed from static/lillogo.png) | bin | 230 -> 230 bytes | |||
| -rwxr-xr-x | static/trash/log4.png (renamed from static/log4.png) | bin | 1640 -> 1640 bytes | |||
| -rwxr-xr-x | static/trash/logo.png (renamed from static/logo.png) | bin | 2706 -> 2706 bytes | |||
| -rwxr-xr-x | static/trash/lolz.gif (renamed from static/lolz.gif) | bin | 23281 -> 23281 bytes | |||
| -rwxr-xr-x | static/trash/main.css (renamed from static/main.css) | 0 | ||||
| -rwxr-xr-x | static/trash/main2.css (renamed from static/main2.css) | 0 | ||||
| -rwxr-xr-x | static/trash/mark1.png (renamed from static/mark1.png) | bin | 3956 -> 3956 bytes | |||
| -rwxr-xr-x | static/trash/mask_shaq.jpg (renamed from static/mask_shaq.jpg) | bin | 251039 -> 251039 bytes | |||
| -rwxr-xr-x | static/trash/mouseover.gif (renamed from static/mouseover.gif) | bin | 9569 -> 9569 bytes | |||
| -rwxr-xr-x | static/trash/over.png (renamed from static/over.png) | bin | 12633 -> 12633 bytes | |||
| -rwxr-xr-x | static/trash/rhianamoney.gif (renamed from static/rhianamoney.gif) | bin | 337134 -> 337134 bytes | |||
| -rwxr-xr-x | static/trash/s.png (renamed from static/s.png) | bin | 115 -> 115 bytes | |||
| -rwxr-xr-x | static/trash/shaq.gif (renamed from static/shaq.gif) | bin | 118610 -> 118610 bytes | |||
| -rwxr-xr-x | static/trash/shaqg.gif (renamed from static/shaqg.gif) | bin | 87735 -> 87735 bytes | |||
| -rwxr-xr-x | static/trash/slo.png (renamed from static/slo.png) | bin | 3471 -> 3471 bytes | |||
| -rwxr-xr-x | static/trash/spex.png (renamed from static/spex.png) | bin | 2404 -> 2404 bytes | |||
| -rwxr-xr-x | static/trash/spinner.gif (renamed from static/spinner.gif) | bin | 1849 -> 1849 bytes | |||
| -rwxr-xr-x | static/trash/startpage.html (renamed from static/startpage.html) | 0 | ||||
| -rwxr-xr-x | static/trash/startpage1.html (renamed from static/startpage1.html) | 0 | ||||
| -rwxr-xr-x | static/trash/startpage7.html (renamed from static/startpage7.html) | 0 | ||||
| -rwxr-xr-x | static/trash/starts/bg4.png (renamed from static/starts/bg4.png) | bin | 5469 -> 5469 bytes | |||
| -rwxr-xr-x | static/trash/starts/bottoml.png (renamed from static/starts/bottoml.png) | bin | 660 -> 660 bytes | |||
| -rwxr-xr-x | static/trash/starts/bottomr.png (renamed from static/starts/bottomr.png) | bin | 649 -> 649 bytes | |||
| -rwxr-xr-x | static/trash/starts/cloudbg.png (renamed from static/starts/cloudbg.png) | bin | 8386 -> 8386 bytes | |||
| -rwxr-xr-x | static/trash/starts/cloudbg1.png (renamed from static/starts/cloudbg1.png) | bin | 8386 -> 8386 bytes | |||
| -rwxr-xr-x | static/trash/starts/getstarted.gif (renamed from static/starts/getstarted.gif) | bin | 6297 -> 6297 bytes | |||
| -rwxr-xr-x | static/trash/starts/index.html (renamed from static/starts/index.html) | 0 | ||||
| -rwxr-xr-x | static/trash/starts/logbg.png (renamed from static/starts/logbg.png) | bin | 820 -> 820 bytes | |||
| -rwxr-xr-x | static/trash/starts/main.css (renamed from static/starts/main.css) | 0 | ||||
| -rwxr-xr-x | static/trash/starts/mark1.png (renamed from static/starts/mark1.png) | bin | 3956 -> 3956 bytes | |||
| -rwxr-xr-x | static/trash/starts/startpage1.html (renamed from static/starts/startpage1.html) | 0 | ||||
| -rwxr-xr-x | static/trash/starts/topl.png (renamed from static/starts/topl.png) | bin | 679 -> 679 bytes | |||
| -rwxr-xr-x | static/trash/starts/topr.png (renamed from static/starts/topr.png) | bin | 651 -> 651 bytes | |||
| -rwxr-xr-x | static/trash/style.css (renamed from static/style.css) | 0 | ||||
| -rwxr-xr-x | static/trash/topb.png (renamed from static/topb.png) | bin | 266 -> 266 bytes | |||
| -rwxr-xr-x | static/trash/topbg.gif (renamed from static/topbg.gif) | bin | 119 -> 119 bytes | |||
| -rwxr-xr-x | static/trash/topbi.gif (renamed from static/topbi.gif) | bin | 868 -> 868 bytes | |||
| -rwxr-xr-x | static/trash/topl.png (renamed from static/topl.png) | bin | 679 -> 679 bytes | |||
| -rwxr-xr-x | static/trash/topr.png (renamed from static/topr.png) | bin | 651 -> 651 bytes | |||
| -rwxr-xr-x | static/trash/try.gif (renamed from static/try.gif) | bin | 25331 -> 25331 bytes | |||
| -rwxr-xr-x | static/trash/try.png (renamed from static/try.png) | bin | 2265 -> 2265 bytes | |||
| -rwxr-xr-x | static/trash/uggs.gif (renamed from static/uggs.gif) | bin | 4436 -> 4436 bytes | |||
| -rwxr-xr-x | static/trash/up.png (renamed from static/up.png) | bin | 4951 -> 4951 bytes | |||
| -rw-r--r-- | static/trash/upload1.png (renamed from static/upload1.png) | bin | 2806 -> 2806 bytes | |||
| -rw-r--r-- | static/trash/upload2.png (renamed from static/upload2.png) | bin | 1167 -> 1167 bytes | |||
| -rw-r--r-- | static/trash/upload3.png (renamed from static/upload3.png) | bin | 1098 -> 1098 bytes | |||
| -rw-r--r-- | static/trash/upload4.png (renamed from static/upload4.png) | bin | 1293 -> 1293 bytes | |||
| -rw-r--r-- | static/trash/upload5.png (renamed from static/upload5.png) | bin | 1727 -> 1727 bytes | |||
| -rw-r--r-- | static/trash/upload6.png (renamed from static/upload6.png) | bin | 215 -> 215 bytes | |||
| -rw-r--r-- | static/trash/upload7.png (renamed from static/upload7.png) | bin | 213 -> 213 bytes | |||
| -rw-r--r-- | static/trash/upload8.png (renamed from static/upload8.png) | bin | 203 -> 203 bytes | |||
| -rw-r--r-- | static/trash/url1.png (renamed from static/url1.png) | bin | 221 -> 221 bytes | |||
| -rwxr-xr-x | static/trash/wayne.gif (renamed from static/wayne.gif) | bin | 58068 -> 58068 bytes | |||
| -rwxr-xr-x | static/trash/wordlogo.gif (renamed from static/wordlogo.gif) | bin | 7314 -> 7314 bytes | |||
| -rwxr-xr-x | static/trash/wordlogo2.gif (renamed from static/wordlogo2.gif) | bin | 8515 -> 8515 bytes | |||
| -rwxr-xr-x | static/trash/yb.png (renamed from static/yb.png) | bin | 665 -> 665 bytes | |||
| -rw-r--r-- | static/urlbutton.png | bin | 3288 -> 2879 bytes | |||
| -rw-r--r-- | static/webcam/webcam.js | 3 | ||||
| -rw-r--r-- | static/webcam/webcam.swf | bin | 6932 -> 18933 bytes | |||
| -rwxr-xr-x | template/banner.st | 6 | ||||
| -rwxr-xr-x | template/chat.st | 32 | ||||
| -rwxr-xr-x | template/head.st | 3 | ||||
| -rwxr-xr-x | template/logged_dump.st | 20 | ||||
| -rwxr-xr-x | template/profile.st | 2 | ||||
| -rw-r--r-- | template/xd_receiver.htm | 1 | ||||
| -rw-r--r-- | webcam/Webcam.as | 2 | ||||
| -rw-r--r-- | webcam/Webcam.fla | bin | 47104 -> 57344 bytes | |||
| -rw-r--r-- | webcam/com/adobe/images/BitString.as | 82 | ||||
| -rw-r--r-- | webcam/com/adobe/images/JPGEncoder.as | 1302 | ||||
| -rw-r--r-- | webcam/com/adobe/images/PNGEncoder.as | 286 | ||||
| -rwxr-xr-x | webcam/com/neave/media/NeaveCamera.as | 81 | ||||
| -rwxr-xr-x | webcam/com/neave/media/NeaveMicrophone.as | 104 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/NeaveWebcam.as | 198 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/AbstractEffect.as | 81 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/EffectEvent.as | 23 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/EffectType.as | 1 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/EffectsManager.as | 1 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/NormalEffect.as | 38 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/color/GlowEffect.as | 68 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/color/MonochromeEffect.as | 61 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/color/RainbowEffect.as | 90 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/color/SepiaDirt.as | 31 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/color/SepiaEffect.as | 90 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/color/WarholEffect.as | 99 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/color/XRayEffect.as | 62 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/delay/DivideEffect.as | 99 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/delay/FilmstripEffect.as | 91 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/delay/GhostEffect.as | 89 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/delay/SlitScanEffect.as | 178 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/delay/TrailEffect.as | 68 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/displace/AbstractDisplaceEffect.as | 64 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/displace/BulgeEffect.as | 74 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/displace/DentEffect.as | 75 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/displace/FishbowlEffect.as | 72 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/displace/FisheyeEffect.as | 72 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/displace/FragmentEffect.as | 101 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/displace/SqueezeEffect.as | 87 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/displace/WaterEffect.as | 76 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/mirror/AbstractMirrorEffect.as | 68 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/mirror/BottomMirrorEffect.as | 41 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/mirror/InverseMirrorEffect.as | 41 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/mirror/LeftMirrorEffect.as | 41 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/mirror/QuadMirrorEffect.as | 97 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/mirror/RightMirrorEffect.as | 44 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/mirror/TopMirrorEffect.as | 44 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/mirror/UpsideDownEffect.as | 54 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/motion/AbstractMotionEffect.as | 138 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/motion/FireEffect.as | 129 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/motion/SnowEffect.as | 154 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/motion/Snowflake.as | 66 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/motion/SteamEffect.as | 73 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/motion/SwarmEffect.as | 106 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/motion/SwarmFly.as | 122 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/pixel/ASCIIEffect.as | 225 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/pixel/HalftoneDot.as | 33 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/pixel/HalftoneEffect.as | 135 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/pixel/PixelateEffect.as | 75 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/pixel/RGBEffect.as | 126 | ||||
| -rwxr-xr-x | webcam/com/neave/webcam/effects/pixel/RGBPixel.as | 34 | ||||
| -rwxr-xr-x | webcam/media/NeaveCamera.as | 81 | ||||
| -rwxr-xr-x | webcam/media/NeaveMicrophone.as | 104 | ||||
| -rw-r--r-- | webcam/webcam.swf | bin | 0 -> 18552 bytes | |||
| -rwxr-xr-x | webcam/webcam/NeaveWebcam.as | 196 | ||||
| -rwxr-xr-x | webcam/webcam/effects/AbstractEffect.as | 81 | ||||
| -rwxr-xr-x | webcam/webcam/effects/EffectEvent.as | 23 | ||||
| -rwxr-xr-x | webcam/webcam/effects/EffectType.as | 55 | ||||
| -rwxr-xr-x | webcam/webcam/effects/EffectsManager.as | 156 | ||||
| -rwxr-xr-x | webcam/webcam/effects/NormalEffect.as | 38 | ||||
| -rwxr-xr-x | webcam/webcam/effects/color/GlowEffect.as | 68 | ||||
| -rwxr-xr-x | webcam/webcam/effects/color/MonochromeEffect.as | 61 | ||||
| -rwxr-xr-x | webcam/webcam/effects/color/RainbowEffect.as | 90 | ||||
| -rwxr-xr-x | webcam/webcam/effects/color/SepiaDirt.as | 31 | ||||
| -rwxr-xr-x | webcam/webcam/effects/color/SepiaEffect.as | 90 | ||||
| -rwxr-xr-x | webcam/webcam/effects/color/WarholEffect.as | 99 | ||||
| -rwxr-xr-x | webcam/webcam/effects/color/XRayEffect.as | 62 | ||||
| -rwxr-xr-x | webcam/webcam/effects/delay/DivideEffect.as | 99 | ||||
| -rwxr-xr-x | webcam/webcam/effects/delay/FilmstripEffect.as | 91 | ||||
| -rwxr-xr-x | webcam/webcam/effects/delay/GhostEffect.as | 89 | ||||
| -rwxr-xr-x | webcam/webcam/effects/delay/SlitScanEffect.as | 178 | ||||
| -rwxr-xr-x | webcam/webcam/effects/delay/TrailEffect.as | 68 | ||||
| -rwxr-xr-x | webcam/webcam/effects/displace/AbstractDisplaceEffect.as | 64 | ||||
| -rwxr-xr-x | webcam/webcam/effects/displace/BulgeEffect.as | 74 | ||||
| -rwxr-xr-x | webcam/webcam/effects/displace/DentEffect.as | 75 | ||||
| -rwxr-xr-x | webcam/webcam/effects/displace/FishbowlEffect.as | 72 | ||||
| -rwxr-xr-x | webcam/webcam/effects/displace/FisheyeEffect.as | 72 | ||||
| -rwxr-xr-x | webcam/webcam/effects/displace/FragmentEffect.as | 101 | ||||
| -rwxr-xr-x | webcam/webcam/effects/displace/SqueezeEffect.as | 87 | ||||
| -rwxr-xr-x | webcam/webcam/effects/displace/WaterEffect.as | 76 | ||||
| -rwxr-xr-x | webcam/webcam/effects/mirror/AbstractMirrorEffect.as | 68 | ||||
| -rwxr-xr-x | webcam/webcam/effects/mirror/BottomMirrorEffect.as | 41 | ||||
| -rwxr-xr-x | webcam/webcam/effects/mirror/InverseMirrorEffect.as | 41 | ||||
| -rwxr-xr-x | webcam/webcam/effects/mirror/LeftMirrorEffect.as | 41 | ||||
| -rwxr-xr-x | webcam/webcam/effects/mirror/QuadMirrorEffect.as | 97 | ||||
| -rwxr-xr-x | webcam/webcam/effects/mirror/RightMirrorEffect.as | 44 | ||||
| -rwxr-xr-x | webcam/webcam/effects/mirror/TopMirrorEffect.as | 44 | ||||
| -rwxr-xr-x | webcam/webcam/effects/mirror/UpsideDownEffect.as | 54 | ||||
| -rwxr-xr-x | webcam/webcam/effects/motion/AbstractMotionEffect.as | 138 | ||||
| -rwxr-xr-x | webcam/webcam/effects/motion/FireEffect.as | 129 | ||||
| -rwxr-xr-x | webcam/webcam/effects/motion/SnowEffect.as | 154 | ||||
| -rwxr-xr-x | webcam/webcam/effects/motion/Snowflake.as | 66 | ||||
| -rwxr-xr-x | webcam/webcam/effects/motion/SteamEffect.as | 73 | ||||
| -rwxr-xr-x | webcam/webcam/effects/motion/SwarmEffect.as | 106 | ||||
| -rwxr-xr-x | webcam/webcam/effects/motion/SwarmFly.as | 122 | ||||
| -rwxr-xr-x | webcam/webcam/effects/pixel/ASCIIEffect.as | 225 | ||||
| -rwxr-xr-x | webcam/webcam/effects/pixel/HalftoneDot.as | 33 | ||||
| -rwxr-xr-x | webcam/webcam/effects/pixel/HalftoneEffect.as | 135 | ||||
| -rwxr-xr-x | webcam/webcam/effects/pixel/PixelateEffect.as | 75 | ||||
| -rwxr-xr-x | webcam/webcam/effects/pixel/RGBEffect.as | 126 | ||||
| -rwxr-xr-x | webcam/webcam/effects/pixel/RGBPixel.as | 34 |
243 files changed, 9939 insertions, 1071 deletions
diff --git a/src/site.clj b/src/site.clj index fe0ed5f..75b0f52 100755 --- a/src/site.clj +++ b/src/site.clj @@ -285,7 +285,9 @@ ;; Landing (defn landing [session] - (redirect-to "/chat")) + (if (session :nick) + (redirect-to "/chat") + (serve-file "static" "index.html"))) (defn login [session params cookies] (let [nick (params :nick) diff --git a/static/ako.gif b/static/ako.gif Binary files differnew file mode 100644 index 0000000..3f94cfa --- /dev/null +++ b/static/ako.gif diff --git a/static/beingpostednow.png b/static/beingpostednow.png Binary files differnew file mode 100644 index 0000000..5087009 --- /dev/null +++ b/static/beingpostednow.png diff --git a/static/duh.gif b/static/duh.gif Binary files differnew file mode 100644 index 0000000..d39158e --- /dev/null +++ b/static/duh.gif diff --git a/static/dump.css b/static/dump.css index 36f3231..f8bbe30 100755 --- a/static/dump.css +++ b/static/dump.css @@ -61,6 +61,16 @@ right:2; bottom:30; } +#effects-msg{ +position:fixed; +bottom:68; +z-index:1111; +right:38; +font-size:15; +color:#fff; +text-shadow: #000 1px 1px 1px; + +} #footerc { text-align:center; diff --git a/static/dumpnewuser.css b/static/dumpnewuser.css index c15f432..313c228 100644 --- a/static/dumpnewuser.css +++ b/static/dumpnewuser.css @@ -22,6 +22,14 @@ z-index:2000; right:20px; bottom:39px; } +#registerlink{ +top:7; +padding:5; +position:fixed; +} +#registerlink img{ +margin-right:5; +} #userlisthelp{ position:fixed; top:100px; @@ -50,7 +58,7 @@ right:10px; } #readyjoin{ position:fixed; -top:27px; +top:23px; left:180px; z-index:2000; } diff --git a/static/dumppreview.gif b/static/dumppreview.gif Binary files differnew file mode 100644 index 0000000..3bb83f0 --- /dev/null +++ b/static/dumppreview.gif diff --git a/static/dumppreview.png b/static/dumppreview.png Binary files differnew file mode 100644 index 0000000..0e3c52d --- /dev/null +++ b/static/dumppreview.png diff --git a/static/hugescreen.png b/static/hugescreen.png Binary files differnew file mode 100644 index 0000000..eb0266f --- /dev/null +++ b/static/hugescreen.png diff --git a/static/ieburnbtn.gif b/static/ieburnbtn.gif Binary files differnew file mode 100644 index 0000000..266ccd2 --- /dev/null +++ b/static/ieburnbtn.gif diff --git a/static/imageboard.png b/static/imageboard.png Binary files differindex 807f1dd..7e917f2 100644 --- a/static/imageboard.png +++ b/static/imageboard.png diff --git a/static/index.html b/static/index.html index e8ec712..d8e0de1 100755 --- a/static/index.html +++ b/static/index.html @@ -1,196 +1,198 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> + <title>dump.fm</title> + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> + <META NAME="keywords" CONTENT="dump.fm, image chat, realtime, internet 3.0, dump, dump fm, image dump, pictures, image links, image board"> + <META NAME="description" CONTENT="Talk with pictures!"> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> <script type="text/javascript" src="/static/js/sha1.js"></script> <script type="text/javascript" src="/static/js/home.js"></script> + <script> + $(document).ready(initLoginForm); + </script> <link rel="stylesheet" type="text/css" href="static/reset.css"> <link rel="shortcut icon" href="static/favicon.ico"> - <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>dump.fm</title></head> - <style type="text/css"> + <style type="text/css"> + body { + background:#EEF2FF url(/static/fade-blue.png) top center repeat-x; + background-repeat:repeat-x; + background-position:top; + margin:6%; + } + #preload { + position: absolute; + left: 0px; + top: 0px; + } + #main { + width:460px; + margin: 0 auto 0 auto; + padding: 19px 0; + border-radius: 15px; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border:solid 1px #fff; + position: relative; + box-shadow: 0 0 10px #d8dbde, 0px 0px 10px #d8dbde; + -webkit-box-shadow: 0 0 10px #d8dbde, 0px 0px 10px #d8dbde; + -moz-box-shadow: 0 0 10px #d8dbde, 0px 0px 10px #d8dbde; + } + #logo-and-text { + position: relative; + z-index: 20; + padding-bottom: 20px; + } -body { - background:#EEF2FF url(/static/fade-blue.png) top center repeat-x; - background-repeat:repeat-x; - background-position:top; - margin:6%; -} -#preload { - position: absolute; - left: 0px; - top: 0px; -} -#main { - width:460px; - margin: 0 auto 0 auto; - padding: 19px 0; - border-radius: 15px; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border:solid 1px #fff; - position: relative; - box-shadow: 0 0 10px #d8dbde, 0px 0px 10px #d8dbde; - -webkit-box-shadow: 0 0 10px #d8dbde, 0px 0px 10px #d8dbde; - -moz-box-shadow: 0 0 10px #d8dbde, 0px 0px 10px #d8dbde; -} -#logo-and-text { - position: relative; - z-index: 20; - padding-bottom: 20px; -} + #horse { + position: absolute; + z-index: 10; + top: 12px; + left: 140px; + } + #remember{ -#horse { - position: absolute; - z-index: 10; - top: 12px; - left: 140px; -} -#remember{ + } + #customer { + position: absolute; + left: -90px; + top: -75px; + z-index: 10; -} -#customer { - position: absolute; - left: -90px; - top: -75px; - z-index: 10; + } + #info { + width:420px; + margin: 11px auto -1px auto; + opacity:0.9; + height:30; + vertical-align: bottom; + } -} -#info { - width:420px; - margin: 11px auto -1px auto; -opacity:0.9; -height:30; - vertical-align: bottom; -} + p { + font-family: Arial, Helvetica, sans-serif; + font-size: 24px; + } -p { - font-family: Arial, Helvetica, sans-serif; - font-size: 24px; -} + .btnav { border: 0px #000 solid;} -.btnav { border: 0px #000 solid;} + .submit { + + text-shadow: -1px 1px 1px #ccc; + font-size:15px; + } -.submit { - - text-shadow: -1px 1px 1px #ccc; - font-size:15px; -} + input { + height:40px; + width:300px; + border:3px #000; + background:#e3e3e3; + margin:10px; + color:#000; + font-size:30px; + + } + .txt { + font-family:Arial, Helvetica, sans-serif; + font-size:14px; + line-height:1.2; + text-shadow:1px 1px 0.5px #ccc; + word-spacing: 3px; + } + .line { + font-family:Arial, Helvetica, sans-serif; + letter-spacing:0px; + line-height:-1; + color:#000; + font-size:17px; + } -input { - height:40px; - width:300px; - border:3px #000; - background:#e3e3e3; - margin:10px; - color:#000; - font-size:30px; - -} -.txt { - font-family:Arial, Helvetica, sans-serif; - font-size:14px; -line-height:1.2; - text-shadow:1px 1px 0.5px #ccc; - word-spacing: 3px; -} - .line { - font-family:Arial, Helvetica, sans-serif; - letter-spacing:0px; -line-height:-1; - color:#000; - font-size:17px; -} + .no-cursor { cursor: none; } + .invisible { display: none !important; } + #cursor-big { position: absolute; z-index: 1000; } -.no-cursor { cursor: none; } -.invisible { display: none !important; } -#cursor-big { position: absolute; z-index: 1000; } + #signin-submit { + display:inline-block; + width:300px; + height:33px; + font-size:20px; + background-image:url(/static/btngrad1.png); + font-weight:bold; + word-spacing:7; + margin-top:12px; + text-align:center; + z-index:100; + font-size:16px; + color:#fff; + text-shadow:1px 1px 3px #000; + border-radius: 5px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px;*/ + border:solid 1px #eee; + } -#signin-submit { - display:inline-block; - width:300px; - height:33px; - font-size:20px; - background-image:url(/static/btngrad1.png); - font-weight:bold; - word-spacing:7; - margin-top:12px; - text-align:center; - z-index:100; - font-size:16px; - color:#fff; - text-shadow:1px 1px 3px #000; - border-radius: 5px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px;*/ - border:solid 1px #eee; -} + #remembermeInput { + width: 15px; + height: 15px; + margin: 1px; + } -#remembermeInput { - width: 15px; - height: 15px; - margin: 1px; -} - -label { - display: block; - width: 300px; - text-align: right; - font-size: 16px; - color: #222; -} - - -</style> -</head> -<body> - <div id="main" align="center"> - - <img src="/static/flyhorse.gif" id="horse" /> - <img src="/static/guaranteed_customer_satisfaction.gif" id="customer" /> - - <div id="registerbox"> - <div id="logo-and-text"> - <a href="/"><img src="/static/dumpmod1.png"></a> - <p align="center" class="line">Talk with pictures!</p> - <div align="right" class="txt"> - <br> - <div align="center">Right now dump.fm is invite only...<br> - If you have a registration code, <a href="/register" style="text-decoration:none;">click here!</a> <br> + label { + display: block; + width: 300px; + text-align: right; + font-size: 16px; + color: #222; + } + </style> + </head> + <body> + <div id="main" align="center"> + + <img src="/static/flyhorse.gif" id="horse" /> + <img src="/static/guaranteed_customer_satisfaction.gif" id="customer" /> + + <div id="registerbox"> + <div id="logo-and-text"> + <a href="/"><img src="/static/dumpmod1.png"></a> + <p align="center" class="line">Talk with pictures!</p> + <div align="right" class="txt"> + <br> + <div align="center">dump.fm lets you talk with pictures<br> + <a href="/register" style="text-decoration:none;">Click here to Register!</a> <br> + </div> </div> + <input type="text" id="nickInput" size="17" /> + <input id="passwordInputLabel" name="passwordInputLabel" size="17" type="text" class="invisible"> + <input type="password" id="passwordInput" size="17" /><br /> + <input id="signin-submit" value="Sign In" /> + <div id="remember"><label> + <input checked="checked" type="checkbox" name="rememberme" id="remembermeInput" /> + Remember Me + </label></div> </div> </div> - <input type="text" id="nickInput" size="17" /> - <input id="passwordInputLabel" name="passwordInputLabel" size="17" type="text" class="invisible"> - <input type="password" id="passwordInput" size="17" /><br /> - <input id="signin-submit" value="Sign In" /> - <div id="remember"><label> - <input checked="checked" type="checkbox" name="rememberme" id="remembermeInput" /> - Remember Me - </label></div> - </div> - </div> - <div id="info" align="right"> - <img src="/static/vxhtml.gif"> - <img src="/static/aol_suck.gif"> - <img src="/static/html_3_2.gif"> - <img src="/static/geocities.gif"> - <img src="/static/valid_html.gif"> - </div> + <div id="info" align="right"> + <img src="/static/vxhtml.gif"> + <img src="/static/aol_suck.gif"> + <img src="/static/html_3_2.gif"> + <img src="/static/geocities.gif"> + <img src="/static/valid_html.gif"> + </div> - <div id="preload"> - <img src="/static/img/cursors/osx.hand.gif" class="no-cursor invisible" id="cursor-big"> - </div> + <div id="preload"> + <img src="/static/img/cursors/osx.hand.gif" class="no-cursor invisible" id="cursor-big"> + </div> - <script type="text/javascript"> - var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); - document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); - </script> - <script type="text/javascript"> - try { - var pageTracker = _gat._getTracker("UA-12364576-1"); - pageTracker._trackPageview(); - } catch(err) {} - </script> -</body> + <script type="text/javascript"> + var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); + document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); + </script> + <script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-12364576-1"); + pageTracker._trackPageview(); + } catch(err) {} + </script> + </body> </html> diff --git a/static/js/pichat.js b/static/js/pichat.js index b4b7c7d..a13b572 100755 --- a/static/js/pichat.js +++ b/static/js/pichat.js @@ -130,9 +130,9 @@ function submitMessage() { var content = $.trim($('#msgInput').val()); $('#msgInput').val(''); if (content == '') { return; } - if (content.length > 6666) { - alert("POST TOO LONG DUDE!"); - return; + if (content.length > 1000) { + alert("POST TOO LONG DUDE!"); + return; } // this shouldn't just be client side :V PendingMessages[content] = true; diff --git a/static/js/register.js b/static/js/register.js index c87eadc..31d32e5 100755 --- a/static/js/register.js +++ b/static/js/register.js @@ -4,15 +4,22 @@ function validateNick(n) { } } -// HOPE NO HACKERS ARE READING THIS :o -var ValidCodes = ['WAXWANYE23', - 'HOTDUMPING5000','RHIZOME','VIP666','HEATNAP','anamanaguchi',]; + +function submitRegistration() { + var nick = $('#nickInput').val(); + var email = $('#emailInput').val(); + var password = $('#passwordInput').val() || "";function validateNick(n) { + if (n.length <= 2) { + return "BAD_NICK_LENGTH"; + } +} + function submitRegistration() { var nick = $('#nickInput').val(); var email = $('#emailInput').val(); var password = $('#passwordInput').val() || ""; - var code = $('#codeInput').val(); + if (nick.length < 3 || nick.length > 12) { alert("Nicks must be between 3 and 12 characters long."); @@ -22,11 +29,66 @@ function submitRegistration() { return; } - if ($.inArray(code.toUpperCase(), ValidCodes) == -1) { - alert("Bad registration code! Try again dude...." ); + + + var hash = hex_sha1(nick + '$' + password + '$dumpfm'); + var onSuccess = function() { + if (typeof pageTracker !== 'undefined') { + pageTracker._trackEvent('User', 'Register', nick); + } + location.href = "/"; + }; + + var onError = function(resp) { + var respText = resp.responseText ? resp.responseText.trim() : false; + if (respText == 'NICK_TAKEN') { + alert("That nick is already taken! Please choose another."); + } else if (respText == 'NICK_INVALID_CHARS') { + alert("Nicks can only contain letters and numbers."); + } else { + alert("Unable to register!"); + } + }; + + $.ajax({ + type: 'POST', + timeout: 5000, + url: 'submit-registration', + data: {'nick': nick, 'email': email, 'hash': hash }, + cache: false, + dataType: 'json', + success: onSuccess, + error: onError + + }); +} + +function initRegister() { + $('#submit').click(submitRegistration); +} + +function handleMsgError(resp) { + var respText = resp.responseText ? resp.responseText.trim() : false; + if (respText == 'UNKNOWN_USER') { + alert("Can't send message! Please login."); + } else if (respText) { + alert("Cannot send message! (" + respText + ")"); + } else { + alert("Cannot send message!"); + } +} + + + if (nick.length < 3 || nick.length > 12) { + alert("Nicks must be between 3 and 12 characters long."); + return; + } else if (password.length < 5) { + alert("Password must be at least 5 characters long."); return; } + + var hash = hex_sha1(nick + '$' + password + '$dumpfm'); var onSuccess = function() { if (typeof pageTracker !== 'undefined') { diff --git a/static/posthere.png b/static/posthere.png Binary files differindex 99d871d..0e3b8f1 100644 --- a/static/posthere.png +++ b/static/posthere.png diff --git a/static/readyjoin.png b/static/readyjoin.png Binary files differindex da8240c..a2b054b 100644 --- a/static/readyjoin.png +++ b/static/readyjoin.png diff --git a/static/register.html b/static/register.html index 2490542..acdb8ed 100644 --- a/static/register.html +++ b/static/register.html @@ -15,6 +15,11 @@ <style type="text/css"> + + +<!-- + + <!-- .white a:link { text-decoration: none; @@ -42,7 +47,7 @@ background-position:center; width:460px; margin: 0px auto -1px auto; - height:400px; +padding:25; padding-top:5; z-index:2; opacity:0.9; @@ -67,7 +72,7 @@ padding-top:5; -webkit-box-shadow: 5px 5px 100px #c8cbce; -moz-box-shadow: 5px 5px 100px #c8cbce; } -#main img{margin-left:80; +#main img{margin-left:100; } #logout7{ @@ -195,6 +200,8 @@ top:15px; --> + + </style> <body> @@ -228,9 +235,6 @@ top:15px; <input type="text" class="field"id="emailInput" /> </h1> - <h1><span> regcode</span> - <input type="text" class="field" id="codeInput" /> - </h1> <h1><br /> diff --git a/static/search/browser.css b/static/search/browser.css new file mode 100755 index 0000000..75b393a --- /dev/null +++ b/static/search/browser.css @@ -0,0 +1,545 @@ +/* pichat.css */ + + body { + font-size:13; + font-family:"Trebuchet MS", Arial, Helvetica, sans-serif; + margin:2%; + background:#EEF2FF url(/static/fade-blue.png) top center repeat-x; + background-repeat:repeat-x; + background-position:top; + +} +#rapper{ +} + #container { + text-align: left; + font-family: sans-serif; + color: #4E4848; + margin-left: auto; + margin-right: auto; + width: 1200px; + } + #description {display:none;width:790px;} + #description div, .post, .result {} + #description p > p,#description p {margin:0;line-height:1;width:auto;} + #description img {float:left;margin:0 12px 12px 0;} +table.search{font-family:Verdana,Arial,Helvetica,sans-serif;text-align:left;font-size:11px;color:#333} +.gsc-trailing-more-results,.gsc-resultsHeader, +.gsc-search-box{display:none;} +.gsc-results{padding-left:0px;} +#searchControl +.gsc-control{width:600;height:30;padding:0px;padding-left:0;}select, label{font:bold 11px Arial,Helvetica,sans-serif;color:#003;text-transform:uppercase;margin-right:5px;} +input#q{width:400;height:25px;font:bold Arial,Helvetica,sans-serif;color:#F00;} +input#submit{ + width:100px; +height:28px; +font-size:20px; +background-image:url(/static/bg-btn-blue.png); + text-align:center; + z-index:100; + cursor:pointer; + background-color:#087cff; + font-size:12px; + color:#fff; + text-shadow:1px 1px 3px rgba(0,0,0,0.5); +} +#logo{padding-left:20;} + +#ish{width:520; +padding:20; +height:550; +background-color:#fff; +border:1px solid #f0e0d6; + box-shadow: 0 0 10px #d8dbde, 0px 0px 10px #d8dbde; + -webkit-box-shadow: 0 0 10px #d8dbde, 0px 0px 10px #d8dbde; + -moz-box-shadow: 0 0 10px #d8dbde, 0px 0px 10px #d8dbde; + background-color:#ffffee; + background-image:url(/static/chanbg.png); + background-repeat:repeat-x; + border-top-left-radius:15px; + border-top-right-radius:15px; + -webkit-border-top-left-radius:15px; + -webkit-border-top-right-radius:15px; + -moz-border-radius-topleft:15px; + -moz-border-radius-topright:15px; + border-bottom-left-radius:15px; + border-bottom-right-radius:15px; + -webkit-border-bottom-left-radius:15px; + -webkit-border-bottom-right-radius:15px; + -moz-border-radius-bottomleft:15px; + -moz-border-radius-bottomright:15px; +} + +#content{ + z-index: 3; + overflow: auto; + min-width:600px; +} + +#chatboxx { + position: fixed; + top:80px; +} + + +#footerc +{ + text-align:center; + position:fixed; + width:100%; + bottom:0px; +line-height:3.1; + font-size:11px; +word-spacing:8px; +height:28px; + color: #000; + +} +#footerc a { + font-size: 11px; + color: #000; +} +#footerc a:link { + text-decoration: none; + font-size: 11px; +color:000; +} + +#footerc a:hover { + text-decoration:none; + font-size: 11px; + color: #f0e; +} + + +#messagePane { + + + +top:40px; +bottom:20px; + position:fixed; + width: 100%; + +left:0.1%; + + z-index:5; +} + +#messageList { + height: 100%; + width: 100%; + overflow-y: auto; + overflow-x: hidden; +} + +#msgInputDiv { + position:relative; + min-width:500px; + z-index:100; +left:1px; +bottom:10px; + width: 100%; +} + +#msgInput { + width: 100%; + z-index:100; + margin-top: 15px; + left:-3px; + position:relative; + border:2px solid #c8cbce; +height:36px; +font-size:20px; + min-width:500px; + + box-shadow: 2px 3px 4px #eee; +-webkit-box-shadow: 2px 3px 4px #eee; +-moz-box-shadow: 2px 3px 4px #eee; +filter: progid:DXImageTransform.Microsoft.dropShadow(color=#eee, offX=3, offY=4, positive=true); +} +.msgInput { + min-width:500px; + z-index:100; +} + +#msgSubmit { + + position:absolute; + display:inline-block; + width:120px; +height:35px; +right:0px; +font-size:20px; +background-image:url(/static/bg-btn-blue.png); +top:15px; + text-align:center; + z-index:100; + cursor:pointer; + background-color:#087cff; + border-top-right-radius:10px; + -webkit-border-top-right-radius:5px; + -moz-border-radius-topright:5px; + border-bottom-right-radius:5px; + -webkit-border-bottom-right-radius:5px; + -moz-border-radius-bottomright:5px; + border-radius:2px; + font-size:12px; + color:#fff; + text-shadow:1px 1px 3px rgba(0,0,0,0.5); +} +.msgDiv img{ + max-width:650px; + width: expression(this.width > 650 ? 650: true); + max-height:400px; + height: expression(this.width > 400 ? 400: true); + max-width:400px; + z-index: 1; +} +.msgDiv {padding:2px; +} +.oldmsg { + color: #666; +} + +#userList { + overflow-x: hidden; + overflow-y:auto; + height: auto; + margin: 0px; + position: absolute; + padding: 5px; + top:85px; + min-width: 150px; + width:11%; + float:right; + right: 6%; + font-family: Arial, Helvetica, sans-serif; + font-size: 14px; + font-weight:420; + border-top-left-radius:5px; + border-top-right-radius:5px; + -webkit-border-top-left-radius:5px; + background-color:#FFF; + -webkit-border-top-right-radius:5px; + -moz-border-radius-topleft:5px; + -moz-border-radius-topright:5px; + border-bottom-left-radius:5px; + border-bottom-right-radius:5px; + -webkit-border-bottom-left-radius:5px; + -webkit-border-bottom-right-radius:5px; + -moz-border-radius-bottomleft:5px; + -moz-border-radius-bottomright:5px; + max-height:450px; + box-shadow: 3px 4px 4px #c8cbce; +-webkit-box-shadow: 3px 4px 4px #c8cbce; +-moz-box-shadow: 3px 3px 4px #c8cbce; +filter: progid:DXImageTransform.Microsoft.dropShadow(color=#c8cbce, offX=3, offY=4, positive=true); + text-overflow:ellipsis; + z-index:18; + text-align: left; +} +.username{height:30px; +margin-top:6px; +line-height:20px; +text-indent:6px; +z-index:18; +min-width:90px; +overflow:hidden; + +} +.username a { +display:block; +width:100%; +height:100%; +text-decoration:none; +} +.username a:hover { +display:block; +width:100%; +height:100%; +background-image:url(/static/moverc.png); +background-repeat:repeat-x; +color:#fff; +text-decoration:none; +background-color:#f3f3f3; + border-top-right-radius:5px; + -webkit-border-top-right-radius:5px; + -moz-border-radius-topright:5px; + border-bottom-right-radius:5px; + -webkit-border-bottom-right-radius:5px; + -moz-border-radius-bottomright:5px; +} +#userList img{ + max-width:30px; + width: expression(this.width > 30 ? 30: true); + max-height:30px; + height: expression(this.width > 30 ? 30: true); + max-width:30px; + + float:right; + right:1px; + z-index:77; + height:30px; + border-top-left-radius:3px; + border-top-right-radius:3px; + -webkit-border-top-left-radius:3px; + -webkit-border-top-right-radius:3px; + -moz-border-radius-topleft:3px; + -moz-border-radius-topright:3px; + border-bottom-left-radius:3px; + border-bottom-right-radius:3px; + -webkit-border-bottom-left-radius:3px; + -webkit-border-bottom-right-radius:3px; + -moz-border-radius-bottomleft:3px; + -moz-border-radius-bottomright:3px; +} + +#userListicon { + overflow: auto; + height: 70%; + margin: 0px; + position: fixed; + padding: 5px; + top:48px; + width: 7%; + float:right; + right: 35px; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + text-transform: uppercase; + min-width:72px; + line-height:13px; + z-index:1; + font-weight: bold; + font-family: Arial, Helvetica, sans-serif; + color: #666; + text-transform:none; + +} +#avatar +{ + right:1px; + float:right; + text-align:left; + width:auto; + +} + +#binfo { + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + bottom + #chatrap{ + top: 105px; + left:0px; + position:absolute; + width: 100%; + padding-bottom:20px; +} +#chatrap{ + top: 105px; + left:0px; + position:absolute; + width: 100%; + padding-bottom:20px; +} + +#input { + padding-right:15px; + line-height:22px; + font-size: 12px; +} + #loghead { + border-bottom:0px; + padding-left: -50px; + margin-right:60%; + width:70%; + letter-spacing:-3px; + color:#504F61; + height:28px; + font-size:33px; + font-family:Arial, Helvetica, sans-serif; + font-weight:bold; + text-transform:capitalize; + text-shadow: -6px 4px 4px #ccc; + padding-bottom:12px; + left: -40px; + background-color: #FFF; + top: 80px; + position: fixed; + } + +#logc +{ + margin-right:10%; + margin-left:10%; + background-color:#FFF; + padding-left: 40px; + padding-bottom: 30px; + padding-top: 15px; +} + + + #profile { + float: right; + border:1px solid #000; + padding: 20px; + width: 180px; + margin-right:15%; + background-color:#FFF; + background-image:url(/static/cloudbg2.png); + background-position:center; + z-index:10; + border-top-right-radius:5px; + -webkit-border-top-right-radius:5px; + -moz-border-radius-topright:5px; + min-height:600px; + } +#chatrap{ + top: 105px; + left:0px; + position:absolute; + width: 100%; + margin: 0; + padding-bottom:105px; +} + +#log +{ + border: 2px #F1F1F1; + margin-right:15%; + margin-left:15%; + background-color:#FFF; + padding-left: 40px; + padding-bottom: 80px; + padding-top: 15px; + min-height: 800px; + border-top-left-radius:5px; + border-top-right-radius:5px; + -webkit-border-top-left-radius:5px; + -webkit-border-top-right-radius:5px; + -moz-border-radius-topleft:5px; + -moz-border-radius-topright:5px; + border-bottom-left-radius:5px; + border-bottom-right-radius:5px; + -webkit-border-bottom-left-radius:5px; + -webkit-border-bottom-right-radius:5px; + -moz-border-radius-bottomleft:5px; + -moz-border-radius-bottomright:5px; +} +#posts { + + + +} +.logged-dump img{ + max-width:650px; + width: expression(this.width > 500 ? 500: true); + max-height:400px; + height: expression(this.width > 500 ? 500: true); + border:0px; + z-index:4; + + + +} +.logged-dump{ + + + + + padding: 15px; + font-family: Arial, Helvetica, sans-serif; + margin-left:15%; + width:60%; + + font-size: 12px; + text-transform: uppercase; + border-top-left-radius:5px;border-top-right-radius:5px;-webkit-border-top-left-radius:5px;-webkit-border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px; + border-bottom-left-radius:5px;border-bottom-right-radius:5px;-webkit-border-bottom-left-radius:5px;-webkit-border-bottom-right-radius:5px;-moz-border-radius-bottomleft:5px;-moz-border-radius-bottomright:5px; + min-width:72px; + line-height:15px; + background-color:#F2F2F2; + background-image:/static/footer.png; + background-position:bottom; + border:solid 1px #0f1e31; + z-index:4; + text-align: left; + margin:15px; + line-height:5px; + + +} + .editable { + color: #0AA; + } + .editing { + color: #F0F; + } + div#avatar { + overflow: hidden; + text-overflow: ellipsis; + } + + img#avatarPic { + max-height:250px; + } + + #logged-dump { + border: 1px solid dotted; + padding: 5px; + } + #loghead { + border-bottom:0px; + padding-left: -50px; + margin-right:60%; + width:auto; + letter-spacing:-3px; + color:#087cff; + height:28px; + font-size:33px; + font-family:Arial, Helvetica, sans-serif; + font-weight:bold; + text-transform:capitalize; + text-shadow: -6px 4px 4px #ccc; + padding-bottom:12px; + left: -40px; + } + #logo7{ + font-size:30; + text-shadow: 1px 1px 1px #000, 2px 3px 1px #f0e; +color:#fff; +font-weight:bold; +} + +p { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 7px; +} +a { + font-size: 12px; + color: #000; +} +a:link { + text-decoration: none; +} +a:visited { + text-decoration: none; + color: #000; +} +a:hover { + text-decoration: none; + color: #00F; +} +a:active { + text-decoration: none; + color: #000; +} +td { + font-family: Arial, Helvetica, sans-serif; + letter-spacing:-1px; + font-size: 12px; + color: #000000; +} +.btnav { border: 0px #000000 solid;} diff --git a/static/search/browser.html b/static/search/browser.html index a3e6f17..98cfd45 100755 --- a/static/search/browser.html +++ b/static/search/browser.html @@ -2,15 +2,13 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>dump.fm</title> - <link rel="stylesheet" type="text/css" href="/static/browser.css"> + <link rel="stylesheet" type="text/css" href="/static/search/browser.css"> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script src="dumpsearch.js" type="text/javascript"></script> - <script type="text/javascript" src="all.js"></script> - <script type="text/javascript" src="cufon-yui.js"></script> <script src="/static/js-global/FancyZoom.js" type="text/javascript"></script> <script src="/static/js-global/FancyZoomHTML.js" type="text/javascript"></script> - <script type="text/javascript" src="futura.js"></script> + </head> <body> @@ -35,15 +33,14 @@ font-weight:bold;">image search</div> <table class="search" width="425" border="0" cellpadding="5" cellspacing="0"> - <a href="#" id="about">options</a></div> + </table> </div> </div> <div id="description"> - <div align="left"><a href="#" class="closeinfo"></a> - </p> + </div> <div> @@ -88,7 +85,7 @@ font-weight:bold;">image search</div> </td> </tr> - <tr> + </tr> <tr> @@ -115,9 +112,9 @@ font-weight:bold;">image search</div> <input type="radio" name="size" value="large" onClick="searchImages();"> Large <input type="radio" name="size" value="xlarge" onClick="searchImages();"> - Extra Large + XXL <input type="radio" name="size" value="0" checked onClick="searchImages();"> - All Sizes</p></td> + Everything</p></td> </tr> <tr> <td colspan="2"><p> @@ -253,7 +250,7 @@ font-weight:bold;">image search</div> type: 'POST', timeout: 5000, url: '/msg', - data: { 'room': 'RoomA', 'content': res.unescapedUrl }, + data: { 'room': 'dumpfm', 'content': res.unescapedUrl }, cache: false, dataType: 'json' }); diff --git a/static/20bar.png b/static/trash/20bar.png Binary files differindex 1bbd234..1bbd234 100644 --- a/static/20bar.png +++ b/static/trash/20bar.png diff --git a/static/20bar2.png b/static/trash/20bar2.png Binary files differindex 1bbd234..1bbd234 100644 --- a/static/20bar2.png +++ b/static/trash/20bar2.png diff --git a/static/20bar3.png b/static/trash/20bar3.png Binary files differindex 1b05876..1b05876 100644 --- a/static/20bar3.png +++ b/static/trash/20bar3.png diff --git a/static/20bar4.png b/static/trash/20bar4.png Binary files differindex 80db403..80db403 100644 --- a/static/20bar4.png +++ b/static/trash/20bar4.png diff --git a/static/20bar5.png b/static/trash/20bar5.png Binary files differindex 51f2a2a..51f2a2a 100644 --- a/static/20bar5.png +++ b/static/trash/20bar5.png diff --git a/static/20bar6.png b/static/trash/20bar6.png Binary files differindex 93dd55a..93dd55a 100644 --- a/static/20bar6.png +++ b/static/trash/20bar6.png diff --git a/static/background13.gif b/static/trash/background13.gif Binary files differindex d087dad..d087dad 100755 --- a/static/background13.gif +++ b/static/trash/background13.gif diff --git a/static/background4.gif b/static/trash/background4.gif Binary files differindex 675add6..675add6 100755 --- a/static/background4.gif +++ b/static/trash/background4.gif diff --git a/static/baygrad.png b/static/trash/baygrad.png Binary files differindex e80c347..e80c347 100644 --- a/static/baygrad.png +++ b/static/trash/baygrad.png diff --git a/static/bg-random.gif b/static/trash/bg-random.gif Binary files differindex 12ce8c5..12ce8c5 100755 --- a/static/bg-random.gif +++ b/static/trash/bg-random.gif diff --git a/static/bg4.png b/static/trash/bg4.png Binary files differindex e20fda8..e20fda8 100755 --- a/static/bg4.png +++ b/static/trash/bg4.png diff --git a/static/bg55.png b/static/trash/bg55.png Binary files differindex f16a548..f16a548 100755 --- a/static/bg55.png +++ b/static/trash/bg55.png diff --git a/static/bgb.png b/static/trash/bgb.png Binary files differindex 3a1c5d2..3a1c5d2 100755 --- a/static/bgb.png +++ b/static/trash/bgb.png diff --git a/static/bgpat.gif b/static/trash/bgpat.gif Binary files differindex 86edce9..86edce9 100755 --- a/static/bgpat.gif +++ b/static/trash/bgpat.gif diff --git a/static/bgto.gif b/static/trash/bgto.gif Binary files differindex 3411a54..3411a54 100755 --- a/static/bgto.gif +++ b/static/trash/bgto.gif diff --git a/static/blink.gif b/static/trash/blink.gif Binary files differindex 0776f7f..0776f7f 100755 --- a/static/blink.gif +++ b/static/trash/blink.gif diff --git a/static/bluego.png b/static/trash/bluego.png Binary files differindex 8bcd35f..8bcd35f 100755 --- a/static/bluego.png +++ b/static/trash/bluego.png diff --git a/static/bottoml.png b/static/trash/bottoml.png Binary files differindex 0f52893..0f52893 100755 --- a/static/bottoml.png +++ b/static/trash/bottoml.png diff --git a/static/bottomr.png b/static/trash/bottomr.png Binary files differindex 5904272..5904272 100755 --- a/static/bottomr.png +++ b/static/trash/bottomr.png diff --git a/static/britglobe2.gif b/static/trash/britglobe2.gif Binary files differindex c972e08..c972e08 100755 --- a/static/britglobe2.gif +++ b/static/trash/britglobe2.gif diff --git a/static/brokenlink.gif b/static/trash/brokenlink.gif Binary files differindex 0e18a55..0e18a55 100755 --- a/static/brokenlink.gif +++ b/static/trash/brokenlink.gif diff --git a/static/bubley.png b/static/trash/bubley.png Binary files differindex fe6eb82..fe6eb82 100755 --- a/static/bubley.png +++ b/static/trash/bubley.png diff --git a/static/cat.jpeg b/static/trash/cat.jpeg Binary files differindex f6bfa16..f6bfa16 100755 --- a/static/cat.jpeg +++ b/static/trash/cat.jpeg diff --git a/static/cloudbg.png b/static/trash/cloudbg.png Binary files differindex f397899..f397899 100755 --- a/static/cloudbg.png +++ b/static/trash/cloudbg.png diff --git a/static/cloudbg1.png b/static/trash/cloudbg1.png Binary files differindex f397899..f397899 100755 --- a/static/cloudbg1.png +++ b/static/trash/cloudbg1.png diff --git a/static/cloudbg2.png b/static/trash/cloudbg2.png Binary files differindex a1d2b6e..a1d2b6e 100755 --- a/static/cloudbg2.png +++ b/static/trash/cloudbg2.png diff --git a/static/d.png b/static/trash/d.png Binary files differindex 63a7bbb..63a7bbb 100755 --- a/static/d.png +++ b/static/trash/d.png diff --git a/static/d3d1.gif b/static/trash/d3d1.gif Binary files differindex 0e88f7b..0e88f7b 100755 --- a/static/d3d1.gif +++ b/static/trash/d3d1.gif diff --git a/static/dblue.png b/static/trash/dblue.png Binary files differindex 3a99764..3a99764 100755 --- a/static/dblue.png +++ b/static/trash/dblue.png diff --git a/static/dddump.png b/static/trash/dddump.png Binary files differindex 593f9a2..593f9a2 100755 --- a/static/dddump.png +++ b/static/trash/dddump.png diff --git a/static/dddump2.png b/static/trash/dddump2.png Binary files differindex df200c7..df200c7 100755 --- a/static/dddump2.png +++ b/static/trash/dddump2.png diff --git a/static/dfm.png b/static/trash/dfm.png Binary files differindex 5e8357e..5e8357e 100755 --- a/static/dfm.png +++ b/static/trash/dfm.png diff --git a/static/dumgradbub2.png b/static/trash/dumgradbub2.png Binary files differindex 1de255d..1de255d 100755 --- a/static/dumgradbub2.png +++ b/static/trash/dumgradbub2.png diff --git a/static/dump.gif b/static/trash/dump.gif Binary files differindex f1633be..f1633be 100755 --- a/static/dump.gif +++ b/static/trash/dump.gif diff --git a/static/dumpbgword.gif b/static/trash/dumpbgword.gif Binary files differindex 27754fa..27754fa 100755 --- a/static/dumpbgword.gif +++ b/static/trash/dumpbgword.gif diff --git a/static/dumpbub.png b/static/trash/dumpbub.png Binary files differindex 382a25c..382a25c 100755 --- a/static/dumpbub.png +++ b/static/trash/dumpbub.png diff --git a/static/dumpd.gif b/static/trash/dumpd.gif Binary files differindex e571668..e571668 100755 --- a/static/dumpd.gif +++ b/static/trash/dumpd.gif diff --git a/static/dumpd.png b/static/trash/dumpd.png Binary files differindex 0f56f50..0f56f50 100755 --- a/static/dumpd.png +++ b/static/trash/dumpd.png diff --git a/static/dumpl2.png b/static/trash/dumpl2.png Binary files differindex f0c7263..f0c7263 100755 --- a/static/dumpl2.png +++ b/static/trash/dumpl2.png diff --git a/static/favicon2.ico b/static/trash/favicon2.ico Binary files differindex c64876f..c64876f 100755 --- a/static/favicon2.ico +++ b/static/trash/favicon2.ico diff --git a/static/favicon6.ico b/static/trash/favicon6.ico Binary files differindex 027dae5..027dae5 100755 --- a/static/favicon6.ico +++ b/static/trash/favicon6.ico diff --git a/static/favicon7.ico b/static/trash/favicon7.ico Binary files differindex 064a3f9..064a3f9 100755 --- a/static/favicon7.ico +++ b/static/trash/favicon7.ico diff --git a/static/footer.png b/static/trash/footer.png Binary files differindex d83aafd..d83aafd 100755 --- a/static/footer.png +++ b/static/trash/footer.png diff --git a/static/footer1.png b/static/trash/footer1.png Binary files differindex b471698..b471698 100755 --- a/static/footer1.png +++ b/static/trash/footer1.png diff --git a/static/forealz.gif b/static/trash/forealz.gif Binary files differindex 63723bf..63723bf 100755 --- a/static/forealz.gif +++ b/static/trash/forealz.gif diff --git a/static/fuckit.gif b/static/trash/fuckit.gif Binary files differindex 9f94cf6..9f94cf6 100755 --- a/static/fuckit.gif +++ b/static/trash/fuckit.gif diff --git a/static/gaga.gif b/static/trash/gaga.gif Binary files differindex efaf4eb..efaf4eb 100755 --- a/static/gaga.gif +++ b/static/trash/gaga.gif diff --git a/static/getstarted.gif b/static/trash/getstarted.gif Binary files differindex b581589..b581589 100755 --- a/static/getstarted.gif +++ b/static/trash/getstarted.gif diff --git a/static/getstarted.html b/static/trash/getstarted.html index c1ac1b1..c1ac1b1 100755 --- a/static/getstarted.html +++ b/static/trash/getstarted.html diff --git a/static/headerbg.png b/static/trash/headerbg.png Binary files differindex 9f218f9..9f218f9 100644 --- a/static/headerbg.png +++ b/static/trash/headerbg.png diff --git a/static/headerbg1.png b/static/trash/headerbg1.png Binary files differindex 9f218f9..9f218f9 100644 --- a/static/headerbg1.png +++ b/static/trash/headerbg1.png diff --git a/static/headerbg2.png b/static/trash/headerbg2.png Binary files differindex 71eee98..71eee98 100644 --- a/static/headerbg2.png +++ b/static/trash/headerbg2.png diff --git a/static/headerbg3.png b/static/trash/headerbg3.png Binary files differindex 3c8902b..3c8902b 100644 --- a/static/headerbg3.png +++ b/static/trash/headerbg3.png diff --git a/static/index5.html b/static/trash/index5.html index b30e42f..b30e42f 100755 --- a/static/index5.html +++ b/static/trash/index5.html diff --git a/static/lil-wayne.jpg b/static/trash/lil-wayne.jpg Binary files differindex 34c6481..34c6481 100755 --- a/static/lil-wayne.jpg +++ b/static/trash/lil-wayne.jpg diff --git a/static/lillogo.png b/static/trash/lillogo.png Binary files differindex fff9d17..fff9d17 100755 --- a/static/lillogo.png +++ b/static/trash/lillogo.png diff --git a/static/log4.png b/static/trash/log4.png Binary files differindex de76494..de76494 100755 --- a/static/log4.png +++ b/static/trash/log4.png diff --git a/static/logo.png b/static/trash/logo.png Binary files differindex a52b0c9..a52b0c9 100755 --- a/static/logo.png +++ b/static/trash/logo.png diff --git a/static/lolz.gif b/static/trash/lolz.gif Binary files differindex ce248c5..ce248c5 100755 --- a/static/lolz.gif +++ b/static/trash/lolz.gif diff --git a/static/main.css b/static/trash/main.css index b3eef67..b3eef67 100755 --- a/static/main.css +++ b/static/trash/main.css diff --git a/static/main2.css b/static/trash/main2.css index 5eeab65..5eeab65 100755 --- a/static/main2.css +++ b/static/trash/main2.css diff --git a/static/mark1.png b/static/trash/mark1.png Binary files differindex 50566ba..50566ba 100755 --- a/static/mark1.png +++ b/static/trash/mark1.png diff --git a/static/mask_shaq.jpg b/static/trash/mask_shaq.jpg Binary files differindex 4c04e8b..4c04e8b 100755 --- a/static/mask_shaq.jpg +++ b/static/trash/mask_shaq.jpg diff --git a/static/mouseover.gif b/static/trash/mouseover.gif Binary files differindex 2c6ee3e..2c6ee3e 100755 --- a/static/mouseover.gif +++ b/static/trash/mouseover.gif diff --git a/static/over.png b/static/trash/over.png Binary files differindex f80754b..f80754b 100755 --- a/static/over.png +++ b/static/trash/over.png diff --git a/static/rhianamoney.gif b/static/trash/rhianamoney.gif Binary files differindex 99f348a..99f348a 100755 --- a/static/rhianamoney.gif +++ b/static/trash/rhianamoney.gif diff --git a/static/s.png b/static/trash/s.png Binary files differindex fdc8c1d..fdc8c1d 100755 --- a/static/s.png +++ b/static/trash/s.png diff --git a/static/shaq.gif b/static/trash/shaq.gif Binary files differindex cfdaa11..cfdaa11 100755 --- a/static/shaq.gif +++ b/static/trash/shaq.gif diff --git a/static/shaqg.gif b/static/trash/shaqg.gif Binary files differindex 6106d3d..6106d3d 100755 --- a/static/shaqg.gif +++ b/static/trash/shaqg.gif diff --git a/static/slo.png b/static/trash/slo.png Binary files differindex 6ad74e6..6ad74e6 100755 --- a/static/slo.png +++ b/static/trash/slo.png diff --git a/static/spex.png b/static/trash/spex.png Binary files differindex fd0231f..fd0231f 100755 --- a/static/spex.png +++ b/static/trash/spex.png diff --git a/static/spinner.gif b/static/trash/spinner.gif Binary files differindex 5b33f7e..5b33f7e 100755 --- a/static/spinner.gif +++ b/static/trash/spinner.gif diff --git a/static/startpage.html b/static/trash/startpage.html index 85f3350..85f3350 100755 --- a/static/startpage.html +++ b/static/trash/startpage.html diff --git a/static/startpage1.html b/static/trash/startpage1.html index dbf5edf..dbf5edf 100755 --- a/static/startpage1.html +++ b/static/trash/startpage1.html diff --git a/static/startpage7.html b/static/trash/startpage7.html index eea492c..eea492c 100755 --- a/static/startpage7.html +++ b/static/trash/startpage7.html diff --git a/static/starts/bg4.png b/static/trash/starts/bg4.png Binary files differindex e20fda8..e20fda8 100755 --- a/static/starts/bg4.png +++ b/static/trash/starts/bg4.png diff --git a/static/starts/bottoml.png b/static/trash/starts/bottoml.png Binary files differindex 0f52893..0f52893 100755 --- a/static/starts/bottoml.png +++ b/static/trash/starts/bottoml.png diff --git a/static/starts/bottomr.png b/static/trash/starts/bottomr.png Binary files differindex 5904272..5904272 100755 --- a/static/starts/bottomr.png +++ b/static/trash/starts/bottomr.png diff --git a/static/starts/cloudbg.png b/static/trash/starts/cloudbg.png Binary files differindex f397899..f397899 100755 --- a/static/starts/cloudbg.png +++ b/static/trash/starts/cloudbg.png diff --git a/static/starts/cloudbg1.png b/static/trash/starts/cloudbg1.png Binary files differindex f397899..f397899 100755 --- a/static/starts/cloudbg1.png +++ b/static/trash/starts/cloudbg1.png diff --git a/static/starts/getstarted.gif b/static/trash/starts/getstarted.gif Binary files differindex b581589..b581589 100755 --- a/static/starts/getstarted.gif +++ b/static/trash/starts/getstarted.gif diff --git a/static/starts/index.html b/static/trash/starts/index.html index b309f74..b309f74 100755 --- a/static/starts/index.html +++ b/static/trash/starts/index.html diff --git a/static/starts/logbg.png b/static/trash/starts/logbg.png Binary files differindex 0e41857..0e41857 100755 --- a/static/starts/logbg.png +++ b/static/trash/starts/logbg.png diff --git a/static/starts/main.css b/static/trash/starts/main.css index 8503c50..8503c50 100755 --- a/static/starts/main.css +++ b/static/trash/starts/main.css diff --git a/static/starts/mark1.png b/static/trash/starts/mark1.png Binary files differindex 50566ba..50566ba 100755 --- a/static/starts/mark1.png +++ b/static/trash/starts/mark1.png diff --git a/static/starts/startpage1.html b/static/trash/starts/startpage1.html index b938eb5..b938eb5 100755 --- a/static/starts/startpage1.html +++ b/static/trash/starts/startpage1.html diff --git a/static/starts/topl.png b/static/trash/starts/topl.png Binary files differindex dcfe5b9..dcfe5b9 100755 --- a/static/starts/topl.png +++ b/static/trash/starts/topl.png diff --git a/static/starts/topr.png b/static/trash/starts/topr.png Binary files differindex 9cfab08..9cfab08 100755 --- a/static/starts/topr.png +++ b/static/trash/starts/topr.png diff --git a/static/style.css b/static/trash/style.css index 4524037..4524037 100755 --- a/static/style.css +++ b/static/trash/style.css diff --git a/static/topb.png b/static/trash/topb.png Binary files differindex 51cc4cc..51cc4cc 100755 --- a/static/topb.png +++ b/static/trash/topb.png diff --git a/static/topbg.gif b/static/trash/topbg.gif Binary files differindex 9432446..9432446 100755 --- a/static/topbg.gif +++ b/static/trash/topbg.gif diff --git a/static/topbi.gif b/static/trash/topbi.gif Binary files differindex a032a08..a032a08 100755 --- a/static/topbi.gif +++ b/static/trash/topbi.gif diff --git a/static/topl.png b/static/trash/topl.png Binary files differindex dcfe5b9..dcfe5b9 100755 --- a/static/topl.png +++ b/static/trash/topl.png diff --git a/static/topr.png b/static/trash/topr.png Binary files differindex 9cfab08..9cfab08 100755 --- a/static/topr.png +++ b/static/trash/topr.png diff --git a/static/try.gif b/static/trash/try.gif Binary files differindex cbe2d89..cbe2d89 100755 --- a/static/try.gif +++ b/static/trash/try.gif diff --git a/static/try.png b/static/trash/try.png Binary files differindex a7021f8..a7021f8 100755 --- a/static/try.png +++ b/static/trash/try.png diff --git a/static/uggs.gif b/static/trash/uggs.gif Binary files differindex a8b763a..a8b763a 100755 --- a/static/uggs.gif +++ b/static/trash/uggs.gif diff --git a/static/up.png b/static/trash/up.png Binary files differindex b13da1c..b13da1c 100755 --- a/static/up.png +++ b/static/trash/up.png diff --git a/static/upload1.png b/static/trash/upload1.png Binary files differindex f46b6a8..f46b6a8 100644 --- a/static/upload1.png +++ b/static/trash/upload1.png diff --git a/static/upload2.png b/static/trash/upload2.png Binary files differindex 10b2237..10b2237 100644 --- a/static/upload2.png +++ b/static/trash/upload2.png diff --git a/static/upload3.png b/static/trash/upload3.png Binary files differindex 714acb1..714acb1 100644 --- a/static/upload3.png +++ b/static/trash/upload3.png diff --git a/static/upload4.png b/static/trash/upload4.png Binary files differindex 5771bc7..5771bc7 100644 --- a/static/upload4.png +++ b/static/trash/upload4.png diff --git a/static/upload5.png b/static/trash/upload5.png Binary files differindex 552bab7..552bab7 100644 --- a/static/upload5.png +++ b/static/trash/upload5.png diff --git a/static/upload6.png b/static/trash/upload6.png Binary files differindex 413261d..413261d 100644 --- a/static/upload6.png +++ b/static/trash/upload6.png diff --git a/static/upload7.png b/static/trash/upload7.png Binary files differindex b677b26..b677b26 100644 --- a/static/upload7.png +++ b/static/trash/upload7.png diff --git a/static/upload8.png b/static/trash/upload8.png Binary files differindex 329b072..329b072 100644 --- a/static/upload8.png +++ b/static/trash/upload8.png diff --git a/static/url1.png b/static/trash/url1.png Binary files differindex 51e0b55..51e0b55 100644 --- a/static/url1.png +++ b/static/trash/url1.png diff --git a/static/wayne.gif b/static/trash/wayne.gif Binary files differindex 13dde42..13dde42 100755 --- a/static/wayne.gif +++ b/static/trash/wayne.gif diff --git a/static/wordlogo.gif b/static/trash/wordlogo.gif Binary files differindex dbef59d..dbef59d 100755 --- a/static/wordlogo.gif +++ b/static/trash/wordlogo.gif diff --git a/static/wordlogo2.gif b/static/trash/wordlogo2.gif Binary files differindex b6f22da..b6f22da 100755 --- a/static/wordlogo2.gif +++ b/static/trash/wordlogo2.gif diff --git a/static/yb.png b/static/trash/yb.png Binary files differindex af2e410..af2e410 100755 --- a/static/yb.png +++ b/static/trash/yb.png diff --git a/static/urlbutton.png b/static/urlbutton.png Binary files differindex ef5ab64..1fc486b 100644 --- a/static/urlbutton.png +++ b/static/urlbutton.png diff --git a/static/webcam/webcam.js b/static/webcam/webcam.js index 42af499..f2e287b 100644 --- a/static/webcam/webcam.js +++ b/static/webcam/webcam.js @@ -56,12 +56,15 @@ window.webcam = { $("body").append(camHtml) $("#webcam-button-upload").addClass("invisible") $("#webcam-button-snap").removeClass("invisible") + $("#effects-msg").removeClass("invisible").fadeOut(70000) + blinkStart() }, hide: function() { $("#webcam-button-snap").addClass("invisible") $("#webcam-button-upload").removeClass("invisible") + $("#effects-msg").addClass("invisible") blinkStop() $("#webcam-preview").remove() }, diff --git a/static/webcam/webcam.swf b/static/webcam/webcam.swf Binary files differindex 9285dc9..ce7b114 100644 --- a/static/webcam/webcam.swf +++ b/static/webcam/webcam.swf diff --git a/template/banner.st b/template/banner.st index 5f396bc..9c6198c 100755 --- a/template/banner.st +++ b/template/banner.st @@ -22,9 +22,9 @@ $else$ - -<a href="/register"><img src="/static/answer_good.gif"width="20px" height="20px" />Register</a> - +<div id="registerlink"> +<a href="/register"><img src="/static/ako.gif"width="21px" height="21px" /> Register</a> +</div> $endif$ diff --git a/template/chat.st b/template/chat.st index d8ff954..3bf86ed 100755 --- a/template/chat.st +++ b/template/chat.st @@ -1,9 +1,11 @@ <html> <head> <title>dump.fm</title> + <META NAME="keywords" CONTENT="dump.fm, image chat, realtime, internet 3.0, dump, dump fm, image dump, pictures, image links, image board"> +<META NAME="description" CONTENT="Talk with pictures!"> $head()$ - $if(user_nick)$ - <link rel="stylesheet" type="text/css" href="/static/dump.css"> + $if(user_avatar)$ + $else$ <link rel="stylesheet" type="text/css" href="/static/dumpnewuser.css"> $endif$ @@ -14,6 +16,9 @@ var Nick = $json_user_nick$; var Room = $json_room_key$; var Timestamp = $timestamp$; + function showAlert() { + alert('MUST LOGIN'); +} $if(isadmin)$ var IsAdmin = true; $else$ @@ -71,7 +76,7 @@ function pop(url) }$ <hr /> </div> - $if(user_nick)$ + $if(user_avatar)$ <link rel="stylesheet" type="text/css" href="/static/dump.css"> <div id="msgInputDiv"> <div id="msginputrapper"> <input id="msgInput" class="msgInput" type="input" /> </div> @@ -81,18 +86,18 @@ function pop(url) <input id="webcam-button-upload" value="Webcam" type="submit"> <input id="webcam-button-snap" value="Send Pic" type="submit" class="invisible blink"> <div id="trophy"><a href="javascript:pop('http://www.likeneveralways.com/trash/count/index.php');"class="tooltip" title="Contest Counter"><img src="/static/trophyicon.gif"></a></div> - </div> + </div><div id="effects-msg"class="invisible">click on your face for effects!</div> $else$ - <link rel="stylesheet" type="text/css" href="/static/dump.css"> + <link rel="stylesheet" type="text/css" href="/static/dump.css"> <div id="msgInputDiv"> <div id="msginputrapper"> <input id="msgInput" class="msgInput" type="input" /> </div> - <input id="msgSubmit" type="submit" value="Send" + <input id="msgSubmit" type="submit" value="Send"onClick="showAlert();" /> - <input id="upload" value="Upload" type="submit"> - <input id="webcam-button-upload" value="Webcam" type="submit"> - <input id="webcam-button-snap" value="Send Pic" type="submit" class="invisible blink"> - <div id="trophy"><a href="javascript:pop('http://www.likeneveralways.com/trash/count/index.php');"class="tooltip" title="Contest Counter"><img src="/static/trophyicon.gif"></a></div> + <input id="upload" value="Upload" type="submit"onClick="showAlert();"> + <input id="webcam-button-upload" value="Webcam" type="submit"onClick="showAlert();"> + <input id="webcam-button-snap" value="Send Pic" type="submit" class="invisible blink"onClick="showAlert();"> + <div id="trophy"><a href="javascript:pop('http://www.likeneveralways.com/trash/count/index.php');"class="tooltip" title="Contest Counter"onClick="showAlert();"><img src="/static/trophyicon.gif"></a></div> </div> </div> @@ -107,13 +112,14 @@ $else$ <div id="imageboard"><img src="/static/imageboard.png"></div> <div id="uploadstuff"><img src="/static/uploadstuff.png"></div> <div id="signinblurb"><img src="/static/signinblurb.png"></div> - <div id="readyjoin"><img src="/static/readyjoin.png"></div> - <div id="dumppreview"><img src="/static/dumppreview.png"></div> + <div id="beingpostednow"><img src="/static/beingpostednow.png"></div> <script> - jQuery(document).ready(function(){ setTimeout( function(){ jQuery("#newuserwrap div").hide(1000) }, 100000 ) }) + jQuery(document).ready(function(){ setTimeout( function(){ jQuery("#newuserwrap div").hide(1000) }, 10000 ) }) </script> + </div> $endif$ + <div id="footerc"> <p> $footer()$ diff --git a/template/head.st b/template/head.st index 7ba802d..9f30ac0 100755 --- a/template/head.st +++ b/template/head.st @@ -1,5 +1,6 @@ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - + <META NAME="keywords" CONTENT="dump.fm, image chat, realtime, internet 3.0, dump, dump fm, image dump, pictures, image links, image board"> +<META NAME="description" CONTENT="Talk with pictures!"> <script type="text/javascript" src="/static/jquery-1.3.2.min.js"></script> <!-- <script type="text/javascript" src="/static/jquery.min.js"></script> --> <!--<script type="text/javascript" src="/static/js/underscore-min.js"></script> --> diff --git a/template/logged_dump.st b/template/logged_dump.st deleted file mode 100755 index 3b8336a..0000000 --- a/template/logged_dump.st +++ /dev/null @@ -1,20 +0,0 @@ - -<div class="logged-dump" id="message-$dump.message_id$"> - <div>$dump.created_on$ -- by <b><a href="/u/$dump.nick$">$dump.nick$</a></b></div> - - <a href="/u/$dump.nick$"> - - <div id="logavatar"> - - $if(dump.avatar)$<img height="50" width="50" src="$dump.avatar$" /> - - $else$ - - <img height="50" width="50" src="/static/noinfo.png"> - - $endif$ - </div></a> - <div class="content">$dump.content$</div> - <hr /> - $share_buttons()$ -</div> diff --git a/template/profile.st b/template/profile.st index 7a3944f..855f8e2 100755 --- a/template/profile.st +++ b/template/profile.st @@ -2,6 +2,8 @@ <html> <head> <title>$nick$'s dump.fm</title> + <META NAME="keywords" CONTENT="dump.fm, image chat, realtime, internet 3.0, dump, dump fm, image dump, pictures, image links, image board"> +<META NAME="description" CONTENT="Talk with pictures!"> $head()$ <link rel="stylesheet" type="text/css" media="screen" href="/static/profile.css"> diff --git a/template/xd_receiver.htm b/template/xd_receiver.htm deleted file mode 100644 index 3c63739..0000000 --- a/template/xd_receiver.htm +++ /dev/null @@ -1 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>xd</title></head><body><script src="http://static.ak.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script></body></html>
\ No newline at end of file diff --git a/webcam/Webcam.as b/webcam/Webcam.as index 7a55373..2077672 100644 --- a/webcam/Webcam.as +++ b/webcam/Webcam.as @@ -1 +1 @@ -package {
/* JPEGCam v1.0.8 */
/* Webcam library for capturing JPEG images and submitting to a server */
/* Copyright (c) 2008 - 2009 Joseph Huckaby <jhuckaby@goldcartridge.com> */
/* Licensed under the GNU Lesser Public License */
/* http://www.gnu.org/licenses/lgpl.html */
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.*;
import flash.utils.*;
import flash.media.Camera;
import flash.media.Video;
import flash.external.ExternalInterface;
import flash.net.*;
import flash.system.Security;
import flash.system.SecurityPanel;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.geom.Matrix;
import com.adobe.images.JPGEncoder;
import com.marstonstudio.UploadPostHelper;
public class Webcam extends Sprite {
private var video:Video;
private var encoder:JPGEncoder;
private var snd:Sound;
private var channel:SoundChannel = new SoundChannel();
private var jpeg_quality:int;
private var video_width:int;
private var video_height:int;
private var server_width:int;
private var server_height:int;
private var camera:Camera;
private var bmp:Bitmap;
private var bmpdata:BitmapData;
private var url:String;
private var form_data:Object;
public function Webcam() {
// class constructor
flash.system.Security.allowDomain("*");
var flashvars:Object = LoaderInfo(this.root.loaderInfo).parameters;
video_width = Math.floor( flashvars.width );
video_height = Math.floor( flashvars.height );
server_width = Math.floor( flashvars.server_width );
server_height = Math.floor( flashvars.server_height );
form_data = {};
stage.scaleMode = StageScaleMode.NO_SCALE;
// stage.scaleMode = StageScaleMode.EXACT_FIT;
stage.align = StageAlign.TOP_LEFT;
stage.stageWidth = Math.max(video_width, server_width);
stage.stageHeight = Math.max(video_height, server_height);
// Hack to auto-select iSight camera on Mac (JPEGCam Issue #5, submitted by manuel.gonzalez.noriega)
// From: http://www.squidder.com/2009/03/09/trick-auto-select-mac-isight-in-flash/
var cameraIdx:int = -1;
for (var idx = 0, len = Camera.names.length; idx < len; idx++) {
if (Camera.names[idx] == "USB Video Class Video") {
cameraIdx = idx;
idx = len;
}
}
if (cameraIdx > -1) camera = Camera.getCamera( String(cameraIdx) );
else camera = Camera.getCamera();
if (camera != null) {
camera.addEventListener(ActivityEvent.ACTIVITY, activityHandler);
video = new Video( Math.max(video_width, server_width), Math.max(video_height, server_height) );
video.attachCamera(camera);
addChild(video);
if ((video_width < server_width) && (video_height < server_height)) {
video.scaleX = video_width / server_width;
video.scaleY = video_height / server_height;
}
camera.setQuality(0, 100);
camera.setKeyFrameInterval(10);
camera.setMode( Math.max(video_width, server_width), Math.max(video_height, server_height), 30);
// do not detect motion (may help reduce CPU usage)
camera.setMotionLevel( 100 );
ExternalInterface.addCallback('_snap', snap);
ExternalInterface.addCallback('_configure', configure);
ExternalInterface.addCallback('_upload', upload);
ExternalInterface.addCallback('_reset', reset);
ExternalInterface.addCallback('_set_form_data', set_form_data);
if (flashvars.shutter_enabled == 1) {
snd = new Sound();
snd.load( new URLRequest( flashvars.shutter_url ) );
}
jpeg_quality = 90;
ExternalInterface.call('webcam.flash_notify', 'flashLoadComplete', true);
}
else {
trace("You need a camera.");
ExternalInterface.call('webcam.flash_notify', "error", "No camera was detected.");
}
}
public function set_quality(new_quality:int) {
// set JPEG image quality
if (new_quality < 0) new_quality = 0;
if (new_quality > 100) new_quality = 100;
jpeg_quality = new_quality;
}
public function set_form_data(new_form_data:Object) {
form_data = new_form_data;
}
public function configure(panel:String = SecurityPanel.CAMERA) {
// show configure dialog inside flash movie
Security.showSettings(panel);
}
private function activityHandler(event:ActivityEvent):void {
trace("activityHandler: " + event);
}
public function snap(url, new_quality, shutter) {
// take snapshot from camera, and upload if URL was provided
if (new_quality) set_quality(new_quality);
trace("in snap(), drawing to bitmap");
if (shutter) {
channel = snd.play();
setTimeout( snap2, 10, url );
}
else snap2(url);
}
public function snap2(url) {
// take snapshot, convert to jpeg, submit to server
bmpdata = new BitmapData( Math.max(video_width, server_width), Math.max(video_height, server_height) );
bmpdata.draw( video );
// draw snapshot on stage
bmp = new Bitmap( bmpdata );
addChild( bmp );
// stop capturing video
video.attachCamera( null );
removeChild( video );
// if URL was provided, upload now
if (url) upload( url );
}
public function upload(url) {
if (bmpdata) {
if ((video_width > server_width) && (video_height > server_height)) {
// resize image downward before submitting
var tmpdata = new BitmapData(server_width, server_height);
var matrix = new Matrix();
matrix.scale( server_width / video_width, server_height / video_height );
tmpdata.draw( bmpdata, matrix, null, null, null, true ); // smoothing
bmpdata = tmpdata;
} // need resize
trace("converting to jpeg");
var ba:ByteArray;
encoder = new JPGEncoder( jpeg_quality );
ba = encoder.encode( bmpdata );
trace("jpeg length: " + ba.length);
//URLRequest containing the form fields and the attached image
var req : URLRequest = new URLRequest(url);
req.method = URLRequestMethod.POST;
req.data = UploadPostHelper.getPostData( 'dump.fm.webcam.test.jpg', ba, form_data );
req.requestHeaders.push(new URLRequestHeader('Cache-Control', 'no-cache') );
req.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary()));
//URLLoader to load the request
var loader : URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoaded);
trace("sending post to: " + url);
try {
loader.load(req);
}
catch (error:Error) {
trace("Unable to load requested document.");
ExternalInterface.call('webcam.flash_notify', "error", "Unable to post data: " + error);
}
}
else {
ExternalInterface.call('webcam.flash_notify', "error", "Nothing to upload, must capture an image first.");
}
}
public function onLoaded(evt:Event):void {
// image upload complete
var msg = "unknown";
if (evt && evt.target && evt.target.data) msg = evt.target.data;
ExternalInterface.call('webcam.flash_notify', "success", msg);
}
public function reset() {
// reset video after taking snapshot
if (bmp) {
removeChild( bmp );
bmp = null;
bmpdata = null;
video.attachCamera(camera);
addChild(video);
}
}
}
}
\ No newline at end of file +package {
/* JPEGCam v1.0.8 */
/* Webcam library for capturing JPEG images and submitting to a server */
/* Copyright (c) 2008 - 2009 Joseph Huckaby <jhuckaby@goldcartridge.com> */
/* Licensed under the GNU Lesser Public License */
/* http://www.gnu.org/licenses/lgpl.html */
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.media.Camera;
import flash.media.Video;
import flash.external.ExternalInterface;
import flash.net.*;
import flash.system.Security;
import flash.system.SecurityPanel;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.geom.Matrix;
import com.adobe.images.JPGEncoder;
import com.marstonstudio.UploadPostHelper;
import com.neave.media.*;
import com.neave.webcam.*;
import com.neave.webcam.effects.*
[SWF(width="320", height="240", frameRate="31", backgroundColor="0x000000")]
public class Webcam extends Sprite {
private var video:Video;
private var webcam:NeaveWebcam;
private var encoder:JPGEncoder;
private var snd:Sound;
private var channel:SoundChannel = new SoundChannel();
private var jpeg_quality:int;
private var video_width:int;
private var video_height:int;
private var server_width:int;
private var server_height:int;
private var camera:Camera;
private var bmp:Bitmap;
private var bmpdata:BitmapData;
private var url:String;
private var form_data:Object;
public function Webcam() {
// class constructor
flash.system.Security.allowDomain("*");
var flashvars:Object = LoaderInfo(this.root.loaderInfo).parameters;
video_width = Math.floor( flashvars.width );
video_height = Math.floor( flashvars.height );
server_width = Math.floor( flashvars.server_width );
server_height = Math.floor( flashvars.server_height );
form_data = {};
stage.scaleMode = StageScaleMode.NO_SCALE;
// stage.scaleMode = StageScaleMode.EXACT_FIT;
stage.align = StageAlign.TOP_LEFT;
stage.stageWidth = Math.max(video_width, server_width);
stage.stageHeight = Math.max(video_height, server_height);
// Hack to auto-select iSight camera on Mac (JPEGCam Issue #5, submitted by manuel.gonzalez.noriega)
// From: http://www.squidder.com/2009/03/09/trick-auto-select-mac-isight-in-flash/
var cameraIdx:int = -1;
for (var idx = 0, len = Camera.names.length; idx < len; idx++) {
if (Camera.names[idx] == "USB Video Class Video") {
cameraIdx = idx;
idx = len;
}
}
if (cameraIdx > -1) camera = Camera.getCamera( String(cameraIdx) );
else camera = Camera.getCamera();
if (camera != null) {
camera.addEventListener(ActivityEvent.ACTIVITY, activityHandler);
video = new Video( Math.max(video_width, server_width), Math.max(video_height, server_height) );
video.attachCamera(camera);
webcam = new NeaveWebcam(camera, true);
addChild(webcam);
if ((video_width < server_width) && (video_height < server_height)) {
video.scaleX = video_width / server_width;
video.scaleY = video_height / server_height;
}
camera.setQuality(0, 100);
camera.setKeyFrameInterval(10);
camera.setMode( Math.max(video_width, server_width), Math.max(video_height, server_height), 30);
// do not detect motion (may help reduce CPU usage)
camera.setMotionLevel( 100 );
ExternalInterface.addCallback('_snap', snap);
ExternalInterface.addCallback('_configure', configure);
ExternalInterface.addCallback('_upload', upload);
ExternalInterface.addCallback('_reset', reset);
ExternalInterface.addCallback('_set_form_data', set_form_data);
if (flashvars.shutter_enabled == 1) {
snd = new Sound();
snd.load( new URLRequest( flashvars.shutter_url ) );
}
jpeg_quality = 90;
ExternalInterface.call('webcam.flash_notify', 'flashLoadComplete', true);
}
else {
trace("You need a camera.");
ExternalInterface.call('webcam.flash_notify', "error", "No camera was detected.");
}
}
public function set_quality(new_quality:int) {
// set JPEG image quality
if (new_quality < 0) new_quality = 0;
if (new_quality > 100) new_quality = 100;
jpeg_quality = new_quality;
}
public function set_form_data(new_form_data:Object) {
form_data = new_form_data;
}
public function configure(panel:String = SecurityPanel.CAMERA) {
// show configure dialog inside flash movie
Security.showSettings(panel);
}
private function activityHandler(event:ActivityEvent):void {
trace("activityHandler: " + event);
}
public function snap(url, new_quality, shutter) {
// take snapshot from camera, and upload if URL was provided
if (new_quality) set_quality(new_quality);
trace("in snap(), drawing to bitmap");
if (shutter) {
channel = snd.play();
setTimeout( snap2, 10, url );
}
else snap2(url);
}
public function snap2(url) {
// take snapshot, convert to jpeg, submit to server
bmpdata = new BitmapData( Math.max(video_width, server_width), Math.max(video_height, server_height) );
bmpdata.draw( webcam.effectBitmap );
// draw snapshot on stage
bmp = new Bitmap( bmpdata );
bmp.scaleX = -1;
addChild( bmp );
// stop capturing video
//video.attachCamera( null );
//removeChild( video );
// if URL was provided, upload now
if (url) upload( url );
}
public function upload(url) {
if (bmpdata) {
if ((video_width > server_width) && (video_height > server_height)) {
// resize image downward before submitting
var tmpdata = new BitmapData(server_width, server_height);
var matrix = new Matrix();
matrix.scale( server_width / video_width, server_height / video_height );
tmpdata.draw( bmpdata, matrix, null, null, null, true ); // smoothing
bmpdata = tmpdata;
} // need resize
trace("converting to jpeg");
var ba:ByteArray;
encoder = new JPGEncoder( jpeg_quality );
ba = encoder.encode( bmpdata );
trace("jpeg length: " + ba.length);
//URLRequest containing the form fields and the attached image
var req : URLRequest = new URLRequest(url);
req.method = URLRequestMethod.POST;
req.data = UploadPostHelper.getPostData( 'dump.fm.webcam.test.jpg', ba, form_data );
req.requestHeaders.push(new URLRequestHeader('Cache-Control', 'no-cache') );
req.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary()));
//URLLoader to load the request
var loader : URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoaded);
trace("sending post to: " + url);
try {
loader.load(req);
}
catch (error:Error) {
trace("Unable to load requested document.");
ExternalInterface.call('webcam.flash_notify', "error", "Unable to post data: " + error);
}
}
else {
ExternalInterface.call('webcam.flash_notify', "error", "Nothing to upload, must capture an image first.");
}
}
public function onLoaded(evt:Event):void {
// image upload complete
var msg = "unknown";
if (evt && evt.target && evt.target.data) msg = evt.target.data;
ExternalInterface.call('webcam.flash_notify', "success", msg);
}
public function reset() {
// reset video after taking snapshot
if (bmp) {
removeChild( bmp );
bmp = null;
bmpdata = null;
/*video.attachCamera(camera);
addChild(video);*/
}
}
}
}
\ No newline at end of file diff --git a/webcam/Webcam.fla b/webcam/Webcam.fla Binary files differindex d4d3f44..c760857 100644 --- a/webcam/Webcam.fla +++ b/webcam/Webcam.fla diff --git a/webcam/com/adobe/images/BitString.as b/webcam/com/adobe/images/BitString.as index 5d89c93..7e1ff14 100644 --- a/webcam/com/adobe/images/BitString.as +++ b/webcam/com/adobe/images/BitString.as @@ -1,42 +1,42 @@ -/* - Adobe Systems Incorporated(r) Source Code License Agreement - Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. - - Please read this Source Code License Agreement carefully before using - the source code. - - Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, - no-charge, royalty-free, irrevocable copyright license, to reproduce, - prepare derivative works of, publicly display, publicly perform, and - distribute this source code and such derivative works in source or - object code form without any attribution requirements. - - The name "Adobe Systems Incorporated" must not be used to endorse or promote products - derived from the source code without prior written permission. - - You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and - against any loss, damage, claims or lawsuits, including attorney's - fees that arise or result from your use or distribution of the source - code. - - THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT - ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF - NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA - OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -package com.adobe.images -{ - public class BitString - { - public var len:int = 0; - public var val:int = 0; - } +/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+package com.adobe.images
+{
+ public class BitString
+ {
+ public var len:int = 0;
+ public var val:int = 0;
+ }
}
\ No newline at end of file diff --git a/webcam/com/adobe/images/JPGEncoder.as b/webcam/com/adobe/images/JPGEncoder.as index 1679976..4c6ad63 100644 --- a/webcam/com/adobe/images/JPGEncoder.as +++ b/webcam/com/adobe/images/JPGEncoder.as @@ -1,651 +1,651 @@ -/* - Adobe Systems Incorporated(r) Source Code License Agreement - Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. - - Please read this Source Code License Agreement carefully before using - the source code. - - Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, - no-charge, royalty-free, irrevocable copyright license, to reproduce, - prepare derivative works of, publicly display, publicly perform, and - distribute this source code and such derivative works in source or - object code form without any attribution requirements. - - The name "Adobe Systems Incorporated" must not be used to endorse or promote products - derived from the source code without prior written permission. - - You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and - against any loss, damage, claims or lawsuits, including attorney's - fees that arise or result from your use or distribution of the source - code. - - THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT - ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF - NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA - OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -package com.adobe.images -{ - import flash.geom.*; - import flash.display.*; - import flash.utils.*; - - /** - * Class that converts BitmapData into a valid JPEG - */ - public class JPGEncoder - { - - // Static table initialization - - private var ZigZag:Array = [ - 0, 1, 5, 6,14,15,27,28, - 2, 4, 7,13,16,26,29,42, - 3, 8,12,17,25,30,41,43, - 9,11,18,24,31,40,44,53, - 10,19,23,32,39,45,52,54, - 20,22,33,38,46,51,55,60, - 21,34,37,47,50,56,59,61, - 35,36,48,49,57,58,62,63 - ]; - - private var YTable:Array = new Array(64); - private var UVTable:Array = new Array(64); - private var fdtbl_Y:Array = new Array(64); - private var fdtbl_UV:Array = new Array(64); - - private function initQuantTables(sf:int):void - { - var i:int; - var t:Number; - var YQT:Array = [ - 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 56, 68,109,103, 77, - 24, 35, 55, 64, 81,104,113, 92, - 49, 64, 78, 87,103,121,120,101, - 72, 92, 95, 98,112,100,103, 99 - ]; - for (i = 0; i < 64; i++) { - t = Math.floor((YQT[i]*sf+50)/100); - if (t < 1) { - t = 1; - } else if (t > 255) { - t = 255; - } - YTable[ZigZag[i]] = t; - } - var UVQT:Array = [ - 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 - ]; - for (i = 0; i < 64; i++) { - t = Math.floor((UVQT[i]*sf+50)/100); - if (t < 1) { - t = 1; - } else if (t > 255) { - t = 255; - } - UVTable[ZigZag[i]] = t; - } - var aasf:Array = [ - 1.0, 1.387039845, 1.306562965, 1.175875602, - 1.0, 0.785694958, 0.541196100, 0.275899379 - ]; - i = 0; - for (var row:int = 0; row < 8; row++) - { - for (var col:int = 0; col < 8; col++) - { - fdtbl_Y[i] = (1.0 / (YTable [ZigZag[i]] * aasf[row] * aasf[col] * 8.0)); - fdtbl_UV[i] = (1.0 / (UVTable[ZigZag[i]] * aasf[row] * aasf[col] * 8.0)); - i++; - } - } - } - - private var YDC_HT:Array; - private var UVDC_HT:Array; - private var YAC_HT:Array; - private var UVAC_HT:Array; - - private function computeHuffmanTbl(nrcodes:Array, std_table:Array):Array - { - var codevalue:int = 0; - var pos_in_table:int = 0; - var HT:Array = new Array(); - for (var k:int=1; k<=16; k++) { - for (var j:int=1; j<=nrcodes[k]; j++) { - HT[std_table[pos_in_table]] = new BitString(); - HT[std_table[pos_in_table]].val = codevalue; - HT[std_table[pos_in_table]].len = k; - pos_in_table++; - codevalue++; - } - codevalue*=2; - } - return HT; - } - - private var std_dc_luminance_nrcodes:Array = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0]; - private var std_dc_luminance_values:Array = [0,1,2,3,4,5,6,7,8,9,10,11]; - private var std_ac_luminance_nrcodes:Array = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d]; - private var std_ac_luminance_values:Array = [ - 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12, - 0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07, - 0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, - 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0, - 0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16, - 0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, - 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39, - 0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49, - 0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, - 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69, - 0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79, - 0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, - 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98, - 0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7, - 0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, - 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5, - 0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4, - 0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, - 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea, - 0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, - 0xf9,0xfa - ]; - - private var std_dc_chrominance_nrcodes:Array = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0]; - private var std_dc_chrominance_values:Array = [0,1,2,3,4,5,6,7,8,9,10,11]; - private var std_ac_chrominance_nrcodes:Array = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77]; - private var std_ac_chrominance_values:Array = [ - 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21, - 0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71, - 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, - 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0, - 0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34, - 0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, - 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38, - 0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48, - 0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, - 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68, - 0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78, - 0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, - 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96, - 0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5, - 0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, - 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3, - 0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2, - 0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, - 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9, - 0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, - 0xf9,0xfa - ]; - - private function initHuffmanTbl():void - { - YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values); - UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values); - YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values); - UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values); - } - - private var bitcode:Array = new Array(65535); - private var category:Array = new Array(65535); - - private function initCategoryNumber():void - { - var nrlower:int = 1; - var nrupper:int = 2; - var nr:int; - for (var cat:int=1; cat<=15; cat++) { - //Positive numbers - for (nr=nrlower; nr<nrupper; nr++) { - category[32767+nr] = cat; - bitcode[32767+nr] = new BitString(); - bitcode[32767+nr].len = cat; - bitcode[32767+nr].val = nr; - } - //Negative numbers - for (nr=-(nrupper-1); nr<=-nrlower; nr++) { - category[32767+nr] = cat; - bitcode[32767+nr] = new BitString(); - bitcode[32767+nr].len = cat; - bitcode[32767+nr].val = nrupper-1+nr; - } - nrlower <<= 1; - nrupper <<= 1; - } - } - - // IO functions - - private var byteout:ByteArray; - private var bytenew:int = 0; - private var bytepos:int = 7; - - private function writeBits(bs:BitString):void - { - var value:int = bs.val; - var posval:int = bs.len-1; - while ( posval >= 0 ) { - if (value & uint(1 << posval) ) { - bytenew |= uint(1 << bytepos); - } - posval--; - bytepos--; - if (bytepos < 0) { - if (bytenew == 0xFF) { - writeByte(0xFF); - writeByte(0); - } - else { - writeByte(bytenew); - } - bytepos=7; - bytenew=0; - } - } - } - - private function writeByte(value:int):void - { - byteout.writeByte(value); - } - - private function writeWord(value:int):void - { - writeByte((value>>8)&0xFF); - writeByte((value )&0xFF); - } - - // DCT & quantization core - - private function fDCTQuant(data:Array, fdtbl:Array):Array - { - var tmp0:Number, tmp1:Number, tmp2:Number, tmp3:Number, tmp4:Number, tmp5:Number, tmp6:Number, tmp7:Number; - var tmp10:Number, tmp11:Number, tmp12:Number, tmp13:Number; - var z1:Number, z2:Number, z3:Number, z4:Number, z5:Number, z11:Number, z13:Number; - var i:int; - /* Pass 1: process rows. */ - var dataOff:int=0; - for (i=0; i<8; i++) { - tmp0 = data[dataOff+0] + data[dataOff+7]; - tmp7 = data[dataOff+0] - data[dataOff+7]; - tmp1 = data[dataOff+1] + data[dataOff+6]; - tmp6 = data[dataOff+1] - data[dataOff+6]; - tmp2 = data[dataOff+2] + data[dataOff+5]; - tmp5 = data[dataOff+2] - data[dataOff+5]; - tmp3 = data[dataOff+3] + data[dataOff+4]; - tmp4 = data[dataOff+3] - data[dataOff+4]; - - /* Even part */ - tmp10 = tmp0 + tmp3; /* phase 2 */ - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - data[dataOff+0] = tmp10 + tmp11; /* phase 3 */ - data[dataOff+4] = tmp10 - tmp11; - - z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */ - data[dataOff+2] = tmp13 + z1; /* phase 5 */ - data[dataOff+6] = tmp13 - z1; - - /* Odd part */ - tmp10 = tmp4 + tmp5; /* phase 2 */ - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */ - z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */ - z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */ - z3 = tmp11 * 0.707106781; /* c4 */ - - z11 = tmp7 + z3; /* phase 5 */ - z13 = tmp7 - z3; - - data[dataOff+5] = z13 + z2; /* phase 6 */ - data[dataOff+3] = z13 - z2; - data[dataOff+1] = z11 + z4; - data[dataOff+7] = z11 - z4; - - dataOff += 8; /* advance pointer to next row */ - } - - /* Pass 2: process columns. */ - dataOff = 0; - for (i=0; i<8; i++) { - tmp0 = data[dataOff+ 0] + data[dataOff+56]; - tmp7 = data[dataOff+ 0] - data[dataOff+56]; - tmp1 = data[dataOff+ 8] + data[dataOff+48]; - tmp6 = data[dataOff+ 8] - data[dataOff+48]; - tmp2 = data[dataOff+16] + data[dataOff+40]; - tmp5 = data[dataOff+16] - data[dataOff+40]; - tmp3 = data[dataOff+24] + data[dataOff+32]; - tmp4 = data[dataOff+24] - data[dataOff+32]; - - /* Even part */ - tmp10 = tmp0 + tmp3; /* phase 2 */ - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - data[dataOff+ 0] = tmp10 + tmp11; /* phase 3 */ - data[dataOff+32] = tmp10 - tmp11; - - z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */ - data[dataOff+16] = tmp13 + z1; /* phase 5 */ - data[dataOff+48] = tmp13 - z1; - - /* Odd part */ - tmp10 = tmp4 + tmp5; /* phase 2 */ - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */ - z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */ - z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */ - z3 = tmp11 * 0.707106781; /* c4 */ - - z11 = tmp7 + z3; /* phase 5 */ - z13 = tmp7 - z3; - - data[dataOff+40] = z13 + z2; /* phase 6 */ - data[dataOff+24] = z13 - z2; - data[dataOff+ 8] = z11 + z4; - data[dataOff+56] = z11 - z4; - - dataOff++; /* advance pointer to next column */ - } - - // Quantize/descale the coefficients - for (i=0; i<64; i++) { - // Apply the quantization and scaling factor & Round to nearest integer - data[i] = Math.round((data[i]*fdtbl[i])); - } - return data; - } - - // Chunk writing - - private function writeAPP0():void - { - writeWord(0xFFE0); // marker - writeWord(16); // length - writeByte(0x4A); // J - writeByte(0x46); // F - writeByte(0x49); // I - writeByte(0x46); // F - writeByte(0); // = "JFIF",'\0' - writeByte(1); // versionhi - writeByte(1); // versionlo - writeByte(0); // xyunits - writeWord(1); // xdensity - writeWord(1); // ydensity - writeByte(0); // thumbnwidth - writeByte(0); // thumbnheight - } - - private function writeSOF0(width:int, height:int):void - { - writeWord(0xFFC0); // marker - writeWord(17); // length, truecolor YUV JPG - writeByte(8); // precision - writeWord(height); - writeWord(width); - writeByte(3); // nrofcomponents - writeByte(1); // IdY - writeByte(0x11); // HVY - writeByte(0); // QTY - writeByte(2); // IdU - writeByte(0x11); // HVU - writeByte(1); // QTU - writeByte(3); // IdV - writeByte(0x11); // HVV - writeByte(1); // QTV - } - - private function writeDQT():void - { - writeWord(0xFFDB); // marker - writeWord(132); // length - writeByte(0); - var i:int; - for (i=0; i<64; i++) { - writeByte(YTable[i]); - } - writeByte(1); - for (i=0; i<64; i++) { - writeByte(UVTable[i]); - } - } - - private function writeDHT():void - { - writeWord(0xFFC4); // marker - writeWord(0x01A2); // length - var i:int; - - writeByte(0); // HTYDCinfo - for (i=0; i<16; i++) { - writeByte(std_dc_luminance_nrcodes[i+1]); - } - for (i=0; i<=11; i++) { - writeByte(std_dc_luminance_values[i]); - } - - writeByte(0x10); // HTYACinfo - for (i=0; i<16; i++) { - writeByte(std_ac_luminance_nrcodes[i+1]); - } - for (i=0; i<=161; i++) { - writeByte(std_ac_luminance_values[i]); - } - - writeByte(1); // HTUDCinfo - for (i=0; i<16; i++) { - writeByte(std_dc_chrominance_nrcodes[i+1]); - } - for (i=0; i<=11; i++) { - writeByte(std_dc_chrominance_values[i]); - } - - writeByte(0x11); // HTUACinfo - for (i=0; i<16; i++) { - writeByte(std_ac_chrominance_nrcodes[i+1]); - } - for (i=0; i<=161; i++) { - writeByte(std_ac_chrominance_values[i]); - } - } - - private function writeSOS():void - { - writeWord(0xFFDA); // marker - writeWord(12); // length - writeByte(3); // nrofcomponents - writeByte(1); // IdY - writeByte(0); // HTY - writeByte(2); // IdU - writeByte(0x11); // HTU - writeByte(3); // IdV - writeByte(0x11); // HTV - writeByte(0); // Ss - writeByte(0x3f); // Se - writeByte(0); // Bf - } - - // Core processing - private var DU:Array = new Array(64); - - private function processDU(CDU:Array, fdtbl:Array, DC:Number, HTDC:Array, HTAC:Array):Number - { - var EOB:BitString = HTAC[0x00]; - var M16zeroes:BitString = HTAC[0xF0]; - var i:int; - - var DU_DCT:Array = fDCTQuant(CDU, fdtbl); - //ZigZag reorder - for (i=0;i<64;i++) { - DU[ZigZag[i]]=DU_DCT[i]; - } - var Diff:int = DU[0] - DC; DC = DU[0]; - //Encode DC - if (Diff==0) { - writeBits(HTDC[0]); // Diff might be 0 - } else { - writeBits(HTDC[category[32767+Diff]]); - writeBits(bitcode[32767+Diff]); - } - //Encode ACs - var end0pos:int = 63; - for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) { - }; - //end0pos = first element in reverse order !=0 - if ( end0pos == 0) { - writeBits(EOB); - return DC; - } - i = 1; - while ( i <= end0pos ) { - var startpos:int = i; - for (; (DU[i]==0) && (i<=end0pos); i++) { - } - var nrzeroes:int = i-startpos; - if ( nrzeroes >= 16 ) { - for (var nrmarker:int=1; nrmarker <= nrzeroes/16; nrmarker++) { - writeBits(M16zeroes); - } - nrzeroes = int(nrzeroes&0xF); - } - writeBits(HTAC[nrzeroes*16+category[32767+DU[i]]]); - writeBits(bitcode[32767+DU[i]]); - i++; - } - if ( end0pos != 63 ) { - writeBits(EOB); - } - return DC; - } - - private var YDU:Array = new Array(64); - private var UDU:Array = new Array(64); - private var VDU:Array = new Array(64); - - private function RGB2YUV(img:BitmapData, xpos:int, ypos:int):void - { - var pos:int=0; - for (var y:int=0; y<8; y++) { - for (var x:int=0; x<8; x++) { - var P:uint = img.getPixel32(xpos+x,ypos+y); - var R:Number = Number((P>>16)&0xFF); - var G:Number = Number((P>> 8)&0xFF); - var B:Number = Number((P )&0xFF); - YDU[pos]=((( 0.29900)*R+( 0.58700)*G+( 0.11400)*B))-128; - UDU[pos]=(((-0.16874)*R+(-0.33126)*G+( 0.50000)*B)); - VDU[pos]=((( 0.50000)*R+(-0.41869)*G+(-0.08131)*B)); - pos++; - } - } - } - - /** - * Constructor for JPEGEncoder class - * - * @param quality The quality level between 1 and 100 that detrmines the - * level of compression used in the generated JPEG - * @langversion ActionScript 3.0 - * @playerversion Flash 9.0 - * @tiptext - */ - public function JPGEncoder(quality:Number = 50) - { - if (quality <= 0) { - quality = 1; - } - if (quality > 100) { - quality = 100; - } - var sf:int = 0; - if (quality < 50) { - sf = int(5000 / quality); - } else { - sf = int(200 - quality*2); - } - // Create tables - initHuffmanTbl(); - initCategoryNumber(); - initQuantTables(sf); - } - - /** - * Created a JPEG image from the specified BitmapData - * - * @param image The BitmapData that will be converted into the JPEG format. - * @return a ByteArray representing the JPEG encoded image data. - * @langversion ActionScript 3.0 - * @playerversion Flash 9.0 - * @tiptext - */ - public function encode(image:BitmapData):ByteArray - { - // Initialize bit writer - byteout = new ByteArray(); - bytenew=0; - bytepos=7; - - // Add JPEG headers - writeWord(0xFFD8); // SOI - writeAPP0(); - writeDQT(); - writeSOF0(image.width,image.height); - writeDHT(); - writeSOS(); - - - // Encode 8x8 macroblocks - var DCY:Number=0; - var DCU:Number=0; - var DCV:Number=0; - bytenew=0; - bytepos=7; - for (var ypos:int=0; ypos<image.height; ypos+=8) { - for (var xpos:int=0; xpos<image.width; xpos+=8) { - RGB2YUV(image, xpos, ypos); - DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); - DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); - DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); - } - } - - // Do the bit alignment of the EOI marker - if ( bytepos >= 0 ) { - var fillbits:BitString = new BitString(); - fillbits.len = bytepos+1; - fillbits.val = (1<<(bytepos+1))-1; - writeBits(fillbits); - } - - writeWord(0xFFD9); //EOI - return byteout; - } - } -} +/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+package com.adobe.images
+{
+ import flash.geom.*;
+ import flash.display.*;
+ import flash.utils.*;
+
+ /**
+ * Class that converts BitmapData into a valid JPEG
+ */
+ public class JPGEncoder
+ {
+
+ // Static table initialization
+
+ private var ZigZag:Array = [
+ 0, 1, 5, 6,14,15,27,28,
+ 2, 4, 7,13,16,26,29,42,
+ 3, 8,12,17,25,30,41,43,
+ 9,11,18,24,31,40,44,53,
+ 10,19,23,32,39,45,52,54,
+ 20,22,33,38,46,51,55,60,
+ 21,34,37,47,50,56,59,61,
+ 35,36,48,49,57,58,62,63
+ ];
+
+ private var YTable:Array = new Array(64);
+ private var UVTable:Array = new Array(64);
+ private var fdtbl_Y:Array = new Array(64);
+ private var fdtbl_UV:Array = new Array(64);
+
+ private function initQuantTables(sf:int):void
+ {
+ var i:int;
+ var t:Number;
+ var YQT:Array = [
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68,109,103, 77,
+ 24, 35, 55, 64, 81,104,113, 92,
+ 49, 64, 78, 87,103,121,120,101,
+ 72, 92, 95, 98,112,100,103, 99
+ ];
+ for (i = 0; i < 64; i++) {
+ t = Math.floor((YQT[i]*sf+50)/100);
+ if (t < 1) {
+ t = 1;
+ } else if (t > 255) {
+ t = 255;
+ }
+ YTable[ZigZag[i]] = t;
+ }
+ var UVQT:Array = [
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99
+ ];
+ for (i = 0; i < 64; i++) {
+ t = Math.floor((UVQT[i]*sf+50)/100);
+ if (t < 1) {
+ t = 1;
+ } else if (t > 255) {
+ t = 255;
+ }
+ UVTable[ZigZag[i]] = t;
+ }
+ var aasf:Array = [
+ 1.0, 1.387039845, 1.306562965, 1.175875602,
+ 1.0, 0.785694958, 0.541196100, 0.275899379
+ ];
+ i = 0;
+ for (var row:int = 0; row < 8; row++)
+ {
+ for (var col:int = 0; col < 8; col++)
+ {
+ fdtbl_Y[i] = (1.0 / (YTable [ZigZag[i]] * aasf[row] * aasf[col] * 8.0));
+ fdtbl_UV[i] = (1.0 / (UVTable[ZigZag[i]] * aasf[row] * aasf[col] * 8.0));
+ i++;
+ }
+ }
+ }
+
+ private var YDC_HT:Array;
+ private var UVDC_HT:Array;
+ private var YAC_HT:Array;
+ private var UVAC_HT:Array;
+
+ private function computeHuffmanTbl(nrcodes:Array, std_table:Array):Array
+ {
+ var codevalue:int = 0;
+ var pos_in_table:int = 0;
+ var HT:Array = new Array();
+ for (var k:int=1; k<=16; k++) {
+ for (var j:int=1; j<=nrcodes[k]; j++) {
+ HT[std_table[pos_in_table]] = new BitString();
+ HT[std_table[pos_in_table]].val = codevalue;
+ HT[std_table[pos_in_table]].len = k;
+ pos_in_table++;
+ codevalue++;
+ }
+ codevalue*=2;
+ }
+ return HT;
+ }
+
+ private var std_dc_luminance_nrcodes:Array = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0];
+ private var std_dc_luminance_values:Array = [0,1,2,3,4,5,6,7,8,9,10,11];
+ private var std_ac_luminance_nrcodes:Array = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d];
+ private var std_ac_luminance_values:Array = [
+ 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,
+ 0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
+ 0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
+ 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,
+ 0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,
+ 0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
+ 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,
+ 0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
+ 0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
+ 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
+ 0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
+ 0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
+ 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
+ 0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
+ 0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
+ 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,
+ 0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,
+ 0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
+ 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,
+ 0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
+ 0xf9,0xfa
+ ];
+
+ private var std_dc_chrominance_nrcodes:Array = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0];
+ private var std_dc_chrominance_values:Array = [0,1,2,3,4,5,6,7,8,9,10,11];
+ private var std_ac_chrominance_nrcodes:Array = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77];
+ private var std_ac_chrominance_values:Array = [
+ 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,
+ 0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
+ 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
+ 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,
+ 0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,
+ 0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
+ 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,
+ 0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,
+ 0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
+ 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,
+ 0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,
+ 0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
+ 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,
+ 0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,
+ 0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
+ 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,
+ 0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,
+ 0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
+ 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,
+ 0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
+ 0xf9,0xfa
+ ];
+
+ private function initHuffmanTbl():void
+ {
+ YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values);
+ UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values);
+ YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values);
+ UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values);
+ }
+
+ private var bitcode:Array = new Array(65535);
+ private var category:Array = new Array(65535);
+
+ private function initCategoryNumber():void
+ {
+ var nrlower:int = 1;
+ var nrupper:int = 2;
+ var nr:int;
+ for (var cat:int=1; cat<=15; cat++) {
+ //Positive numbers
+ for (nr=nrlower; nr<nrupper; nr++) {
+ category[32767+nr] = cat;
+ bitcode[32767+nr] = new BitString();
+ bitcode[32767+nr].len = cat;
+ bitcode[32767+nr].val = nr;
+ }
+ //Negative numbers
+ for (nr=-(nrupper-1); nr<=-nrlower; nr++) {
+ category[32767+nr] = cat;
+ bitcode[32767+nr] = new BitString();
+ bitcode[32767+nr].len = cat;
+ bitcode[32767+nr].val = nrupper-1+nr;
+ }
+ nrlower <<= 1;
+ nrupper <<= 1;
+ }
+ }
+
+ // IO functions
+
+ private var byteout:ByteArray;
+ private var bytenew:int = 0;
+ private var bytepos:int = 7;
+
+ private function writeBits(bs:BitString):void
+ {
+ var value:int = bs.val;
+ var posval:int = bs.len-1;
+ while ( posval >= 0 ) {
+ if (value & uint(1 << posval) ) {
+ bytenew |= uint(1 << bytepos);
+ }
+ posval--;
+ bytepos--;
+ if (bytepos < 0) {
+ if (bytenew == 0xFF) {
+ writeByte(0xFF);
+ writeByte(0);
+ }
+ else {
+ writeByte(bytenew);
+ }
+ bytepos=7;
+ bytenew=0;
+ }
+ }
+ }
+
+ private function writeByte(value:int):void
+ {
+ byteout.writeByte(value);
+ }
+
+ private function writeWord(value:int):void
+ {
+ writeByte((value>>8)&0xFF);
+ writeByte((value )&0xFF);
+ }
+
+ // DCT & quantization core
+
+ private function fDCTQuant(data:Array, fdtbl:Array):Array
+ {
+ var tmp0:Number, tmp1:Number, tmp2:Number, tmp3:Number, tmp4:Number, tmp5:Number, tmp6:Number, tmp7:Number;
+ var tmp10:Number, tmp11:Number, tmp12:Number, tmp13:Number;
+ var z1:Number, z2:Number, z3:Number, z4:Number, z5:Number, z11:Number, z13:Number;
+ var i:int;
+ /* Pass 1: process rows. */
+ var dataOff:int=0;
+ for (i=0; i<8; i++) {
+ tmp0 = data[dataOff+0] + data[dataOff+7];
+ tmp7 = data[dataOff+0] - data[dataOff+7];
+ tmp1 = data[dataOff+1] + data[dataOff+6];
+ tmp6 = data[dataOff+1] - data[dataOff+6];
+ tmp2 = data[dataOff+2] + data[dataOff+5];
+ tmp5 = data[dataOff+2] - data[dataOff+5];
+ tmp3 = data[dataOff+3] + data[dataOff+4];
+ tmp4 = data[dataOff+3] - data[dataOff+4];
+
+ /* Even part */
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ data[dataOff+0] = tmp10 + tmp11; /* phase 3 */
+ data[dataOff+4] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */
+ data[dataOff+2] = tmp13 + z1; /* phase 5 */
+ data[dataOff+6] = tmp13 - z1;
+
+ /* Odd part */
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */
+ z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */
+ z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */
+ z3 = tmp11 * 0.707106781; /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ data[dataOff+5] = z13 + z2; /* phase 6 */
+ data[dataOff+3] = z13 - z2;
+ data[dataOff+1] = z11 + z4;
+ data[dataOff+7] = z11 - z4;
+
+ dataOff += 8; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns. */
+ dataOff = 0;
+ for (i=0; i<8; i++) {
+ tmp0 = data[dataOff+ 0] + data[dataOff+56];
+ tmp7 = data[dataOff+ 0] - data[dataOff+56];
+ tmp1 = data[dataOff+ 8] + data[dataOff+48];
+ tmp6 = data[dataOff+ 8] - data[dataOff+48];
+ tmp2 = data[dataOff+16] + data[dataOff+40];
+ tmp5 = data[dataOff+16] - data[dataOff+40];
+ tmp3 = data[dataOff+24] + data[dataOff+32];
+ tmp4 = data[dataOff+24] - data[dataOff+32];
+
+ /* Even part */
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ data[dataOff+ 0] = tmp10 + tmp11; /* phase 3 */
+ data[dataOff+32] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */
+ data[dataOff+16] = tmp13 + z1; /* phase 5 */
+ data[dataOff+48] = tmp13 - z1;
+
+ /* Odd part */
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */
+ z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */
+ z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */
+ z3 = tmp11 * 0.707106781; /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ data[dataOff+40] = z13 + z2; /* phase 6 */
+ data[dataOff+24] = z13 - z2;
+ data[dataOff+ 8] = z11 + z4;
+ data[dataOff+56] = z11 - z4;
+
+ dataOff++; /* advance pointer to next column */
+ }
+
+ // Quantize/descale the coefficients
+ for (i=0; i<64; i++) {
+ // Apply the quantization and scaling factor & Round to nearest integer
+ data[i] = Math.round((data[i]*fdtbl[i]));
+ }
+ return data;
+ }
+
+ // Chunk writing
+
+ private function writeAPP0():void
+ {
+ writeWord(0xFFE0); // marker
+ writeWord(16); // length
+ writeByte(0x4A); // J
+ writeByte(0x46); // F
+ writeByte(0x49); // I
+ writeByte(0x46); // F
+ writeByte(0); // = "JFIF",'\0'
+ writeByte(1); // versionhi
+ writeByte(1); // versionlo
+ writeByte(0); // xyunits
+ writeWord(1); // xdensity
+ writeWord(1); // ydensity
+ writeByte(0); // thumbnwidth
+ writeByte(0); // thumbnheight
+ }
+
+ private function writeSOF0(width:int, height:int):void
+ {
+ writeWord(0xFFC0); // marker
+ writeWord(17); // length, truecolor YUV JPG
+ writeByte(8); // precision
+ writeWord(height);
+ writeWord(width);
+ writeByte(3); // nrofcomponents
+ writeByte(1); // IdY
+ writeByte(0x11); // HVY
+ writeByte(0); // QTY
+ writeByte(2); // IdU
+ writeByte(0x11); // HVU
+ writeByte(1); // QTU
+ writeByte(3); // IdV
+ writeByte(0x11); // HVV
+ writeByte(1); // QTV
+ }
+
+ private function writeDQT():void
+ {
+ writeWord(0xFFDB); // marker
+ writeWord(132); // length
+ writeByte(0);
+ var i:int;
+ for (i=0; i<64; i++) {
+ writeByte(YTable[i]);
+ }
+ writeByte(1);
+ for (i=0; i<64; i++) {
+ writeByte(UVTable[i]);
+ }
+ }
+
+ private function writeDHT():void
+ {
+ writeWord(0xFFC4); // marker
+ writeWord(0x01A2); // length
+ var i:int;
+
+ writeByte(0); // HTYDCinfo
+ for (i=0; i<16; i++) {
+ writeByte(std_dc_luminance_nrcodes[i+1]);
+ }
+ for (i=0; i<=11; i++) {
+ writeByte(std_dc_luminance_values[i]);
+ }
+
+ writeByte(0x10); // HTYACinfo
+ for (i=0; i<16; i++) {
+ writeByte(std_ac_luminance_nrcodes[i+1]);
+ }
+ for (i=0; i<=161; i++) {
+ writeByte(std_ac_luminance_values[i]);
+ }
+
+ writeByte(1); // HTUDCinfo
+ for (i=0; i<16; i++) {
+ writeByte(std_dc_chrominance_nrcodes[i+1]);
+ }
+ for (i=0; i<=11; i++) {
+ writeByte(std_dc_chrominance_values[i]);
+ }
+
+ writeByte(0x11); // HTUACinfo
+ for (i=0; i<16; i++) {
+ writeByte(std_ac_chrominance_nrcodes[i+1]);
+ }
+ for (i=0; i<=161; i++) {
+ writeByte(std_ac_chrominance_values[i]);
+ }
+ }
+
+ private function writeSOS():void
+ {
+ writeWord(0xFFDA); // marker
+ writeWord(12); // length
+ writeByte(3); // nrofcomponents
+ writeByte(1); // IdY
+ writeByte(0); // HTY
+ writeByte(2); // IdU
+ writeByte(0x11); // HTU
+ writeByte(3); // IdV
+ writeByte(0x11); // HTV
+ writeByte(0); // Ss
+ writeByte(0x3f); // Se
+ writeByte(0); // Bf
+ }
+
+ // Core processing
+ private var DU:Array = new Array(64);
+
+ private function processDU(CDU:Array, fdtbl:Array, DC:Number, HTDC:Array, HTAC:Array):Number
+ {
+ var EOB:BitString = HTAC[0x00];
+ var M16zeroes:BitString = HTAC[0xF0];
+ var i:int;
+
+ var DU_DCT:Array = fDCTQuant(CDU, fdtbl);
+ //ZigZag reorder
+ for (i=0;i<64;i++) {
+ DU[ZigZag[i]]=DU_DCT[i];
+ }
+ var Diff:int = DU[0] - DC; DC = DU[0];
+ //Encode DC
+ if (Diff==0) {
+ writeBits(HTDC[0]); // Diff might be 0
+ } else {
+ writeBits(HTDC[category[32767+Diff]]);
+ writeBits(bitcode[32767+Diff]);
+ }
+ //Encode ACs
+ var end0pos:int = 63;
+ for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {
+ };
+ //end0pos = first element in reverse order !=0
+ if ( end0pos == 0) {
+ writeBits(EOB);
+ return DC;
+ }
+ i = 1;
+ while ( i <= end0pos ) {
+ var startpos:int = i;
+ for (; (DU[i]==0) && (i<=end0pos); i++) {
+ }
+ var nrzeroes:int = i-startpos;
+ if ( nrzeroes >= 16 ) {
+ for (var nrmarker:int=1; nrmarker <= nrzeroes/16; nrmarker++) {
+ writeBits(M16zeroes);
+ }
+ nrzeroes = int(nrzeroes&0xF);
+ }
+ writeBits(HTAC[nrzeroes*16+category[32767+DU[i]]]);
+ writeBits(bitcode[32767+DU[i]]);
+ i++;
+ }
+ if ( end0pos != 63 ) {
+ writeBits(EOB);
+ }
+ return DC;
+ }
+
+ private var YDU:Array = new Array(64);
+ private var UDU:Array = new Array(64);
+ private var VDU:Array = new Array(64);
+
+ private function RGB2YUV(img:BitmapData, xpos:int, ypos:int):void
+ {
+ var pos:int=0;
+ for (var y:int=0; y<8; y++) {
+ for (var x:int=0; x<8; x++) {
+ var P:uint = img.getPixel32(xpos+x,ypos+y);
+ var R:Number = Number((P>>16)&0xFF);
+ var G:Number = Number((P>> 8)&0xFF);
+ var B:Number = Number((P )&0xFF);
+ YDU[pos]=((( 0.29900)*R+( 0.58700)*G+( 0.11400)*B))-128;
+ UDU[pos]=(((-0.16874)*R+(-0.33126)*G+( 0.50000)*B));
+ VDU[pos]=((( 0.50000)*R+(-0.41869)*G+(-0.08131)*B));
+ pos++;
+ }
+ }
+ }
+
+ /**
+ * Constructor for JPEGEncoder class
+ *
+ * @param quality The quality level between 1 and 100 that detrmines the
+ * level of compression used in the generated JPEG
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function JPGEncoder(quality:Number = 50)
+ {
+ if (quality <= 0) {
+ quality = 1;
+ }
+ if (quality > 100) {
+ quality = 100;
+ }
+ var sf:int = 0;
+ if (quality < 50) {
+ sf = int(5000 / quality);
+ } else {
+ sf = int(200 - quality*2);
+ }
+ // Create tables
+ initHuffmanTbl();
+ initCategoryNumber();
+ initQuantTables(sf);
+ }
+
+ /**
+ * Created a JPEG image from the specified BitmapData
+ *
+ * @param image The BitmapData that will be converted into the JPEG format.
+ * @return a ByteArray representing the JPEG encoded image data.
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public function encode(image:BitmapData):ByteArray
+ {
+ // Initialize bit writer
+ byteout = new ByteArray();
+ bytenew=0;
+ bytepos=7;
+
+ // Add JPEG headers
+ writeWord(0xFFD8); // SOI
+ writeAPP0();
+ writeDQT();
+ writeSOF0(image.width,image.height);
+ writeDHT();
+ writeSOS();
+
+
+ // Encode 8x8 macroblocks
+ var DCY:Number=0;
+ var DCU:Number=0;
+ var DCV:Number=0;
+ bytenew=0;
+ bytepos=7;
+ for (var ypos:int=0; ypos<image.height; ypos+=8) {
+ for (var xpos:int=0; xpos<image.width; xpos+=8) {
+ RGB2YUV(image, xpos, ypos);
+ DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
+ DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
+ DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
+ }
+ }
+
+ // Do the bit alignment of the EOI marker
+ if ( bytepos >= 0 ) {
+ var fillbits:BitString = new BitString();
+ fillbits.len = bytepos+1;
+ fillbits.val = (1<<(bytepos+1))-1;
+ writeBits(fillbits);
+ }
+
+ writeWord(0xFFD9); //EOI
+ return byteout;
+ }
+ }
+}
diff --git a/webcam/com/adobe/images/PNGEncoder.as b/webcam/com/adobe/images/PNGEncoder.as index bb86444..f40e575 100644 --- a/webcam/com/adobe/images/PNGEncoder.as +++ b/webcam/com/adobe/images/PNGEncoder.as @@ -1,144 +1,144 @@ -/* - Adobe Systems Incorporated(r) Source Code License Agreement - Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved. - - Please read this Source Code License Agreement carefully before using - the source code. - - Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, - no-charge, royalty-free, irrevocable copyright license, to reproduce, - prepare derivative works of, publicly display, publicly perform, and - distribute this source code and such derivative works in source or - object code form without any attribution requirements. - - The name "Adobe Systems Incorporated" must not be used to endorse or promote products - derived from the source code without prior written permission. - - You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and - against any loss, damage, claims or lawsuits, including attorney's - fees that arise or result from your use or distribution of the source - code. - - THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT - ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF - NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA - OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -package com.adobe.images -{ - import flash.geom.*; - import flash.display.Bitmap; - import flash.display.BitmapData; - import flash.utils.ByteArray; - - /** - * Class that converts BitmapData into a valid PNG - */ - public class PNGEncoder - { - /** - * Created a PNG image from the specified BitmapData - * - * @param image The BitmapData that will be converted into the PNG format. - * @return a ByteArray representing the PNG encoded image data. - * @langversion ActionScript 3.0 - * @playerversion Flash 9.0 - * @tiptext - */ - public static function encode(img:BitmapData):ByteArray { - // Create output byte array - var png:ByteArray = new ByteArray(); - // Write PNG signature - png.writeUnsignedInt(0x89504e47); - png.writeUnsignedInt(0x0D0A1A0A); - // Build IHDR chunk - var IHDR:ByteArray = new ByteArray(); - IHDR.writeInt(img.width); - IHDR.writeInt(img.height); - IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA - IHDR.writeByte(0); - writeChunk(png,0x49484452,IHDR); - // Build IDAT chunk - var IDAT:ByteArray= new ByteArray(); - for(var i:int=0;i < img.height;i++) { - // no filter - IDAT.writeByte(0); - var p:uint; - var j:int; - if ( !img.transparent ) { - for(j=0;j < img.width;j++) { - p = img.getPixel(j,i); - IDAT.writeUnsignedInt( - uint(((p&0xFFFFFF) << 8)|0xFF)); - } - } else { - for(j=0;j < img.width;j++) { - p = img.getPixel32(j,i); - IDAT.writeUnsignedInt( - uint(((p&0xFFFFFF) << 8)| - (p>>>24))); - } - } - } - IDAT.compress(); - writeChunk(png,0x49444154,IDAT); - // Build IEND chunk - writeChunk(png,0x49454E44,null); - // return PNG - return png; - } - - private static var crcTable:Array; - private static var crcTableComputed:Boolean = false; - - private static function writeChunk(png:ByteArray, - type:uint, data:ByteArray):void { - if (!crcTableComputed) { - crcTableComputed = true; - crcTable = []; - var c:uint; - for (var n:uint = 0; n < 256; n++) { - c = n; - for (var k:uint = 0; k < 8; k++) { - if (c & 1) { - c = uint(uint(0xedb88320) ^ - uint(c >>> 1)); - } else { - c = uint(c >>> 1); - } - } - crcTable[n] = c; - } - } - var len:uint = 0; - if (data != null) { - len = data.length; - } - png.writeUnsignedInt(len); - var p:uint = png.position; - png.writeUnsignedInt(type); - if ( data != null ) { - png.writeBytes(data); - } - var e:uint = png.position; - png.position = p; - c = 0xffffffff; - for (var i:int = 0; i < (e-p); i++) { - c = uint(crcTable[ - (c ^ png.readUnsignedByte()) & - uint(0xff)] ^ uint(c >>> 8)); - } - c = uint(c^uint(0xffffffff)); - png.position = e; - png.writeUnsignedInt(c); - } - } +/*
+ Adobe Systems Incorporated(r) Source Code License Agreement
+ Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
+
+ Please read this Source Code License Agreement carefully before using
+ the source code.
+
+ Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
+ no-charge, royalty-free, irrevocable copyright license, to reproduce,
+ prepare derivative works of, publicly display, publicly perform, and
+ distribute this source code and such derivative works in source or
+ object code form without any attribution requirements.
+
+ The name "Adobe Systems Incorporated" must not be used to endorse or promote products
+ derived from the source code without prior written permission.
+
+ You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
+ against any loss, damage, claims or lawsuits, including attorney's
+ fees that arise or result from your use or distribution of the source
+ code.
+
+ THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
+ ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
+ NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
+ OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+package com.adobe.images
+{
+ import flash.geom.*;
+ import flash.display.Bitmap;
+ import flash.display.BitmapData;
+ import flash.utils.ByteArray;
+
+ /**
+ * Class that converts BitmapData into a valid PNG
+ */
+ public class PNGEncoder
+ {
+ /**
+ * Created a PNG image from the specified BitmapData
+ *
+ * @param image The BitmapData that will be converted into the PNG format.
+ * @return a ByteArray representing the PNG encoded image data.
+ * @langversion ActionScript 3.0
+ * @playerversion Flash 9.0
+ * @tiptext
+ */
+ public static function encode(img:BitmapData):ByteArray {
+ // Create output byte array
+ var png:ByteArray = new ByteArray();
+ // Write PNG signature
+ png.writeUnsignedInt(0x89504e47);
+ png.writeUnsignedInt(0x0D0A1A0A);
+ // Build IHDR chunk
+ var IHDR:ByteArray = new ByteArray();
+ IHDR.writeInt(img.width);
+ IHDR.writeInt(img.height);
+ IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA
+ IHDR.writeByte(0);
+ writeChunk(png,0x49484452,IHDR);
+ // Build IDAT chunk
+ var IDAT:ByteArray= new ByteArray();
+ for(var i:int=0;i < img.height;i++) {
+ // no filter
+ IDAT.writeByte(0);
+ var p:uint;
+ var j:int;
+ if ( !img.transparent ) {
+ for(j=0;j < img.width;j++) {
+ p = img.getPixel(j,i);
+ IDAT.writeUnsignedInt(
+ uint(((p&0xFFFFFF) << 8)|0xFF));
+ }
+ } else {
+ for(j=0;j < img.width;j++) {
+ p = img.getPixel32(j,i);
+ IDAT.writeUnsignedInt(
+ uint(((p&0xFFFFFF) << 8)|
+ (p>>>24)));
+ }
+ }
+ }
+ IDAT.compress();
+ writeChunk(png,0x49444154,IDAT);
+ // Build IEND chunk
+ writeChunk(png,0x49454E44,null);
+ // return PNG
+ return png;
+ }
+
+ private static var crcTable:Array;
+ private static var crcTableComputed:Boolean = false;
+
+ private static function writeChunk(png:ByteArray,
+ type:uint, data:ByteArray):void {
+ if (!crcTableComputed) {
+ crcTableComputed = true;
+ crcTable = [];
+ var c:uint;
+ for (var n:uint = 0; n < 256; n++) {
+ c = n;
+ for (var k:uint = 0; k < 8; k++) {
+ if (c & 1) {
+ c = uint(uint(0xedb88320) ^
+ uint(c >>> 1));
+ } else {
+ c = uint(c >>> 1);
+ }
+ }
+ crcTable[n] = c;
+ }
+ }
+ var len:uint = 0;
+ if (data != null) {
+ len = data.length;
+ }
+ png.writeUnsignedInt(len);
+ var p:uint = png.position;
+ png.writeUnsignedInt(type);
+ if ( data != null ) {
+ png.writeBytes(data);
+ }
+ var e:uint = png.position;
+ png.position = p;
+ c = 0xffffffff;
+ for (var i:int = 0; i < (e-p); i++) {
+ c = uint(crcTable[
+ (c ^ png.readUnsignedByte()) &
+ uint(0xff)] ^ uint(c >>> 8));
+ }
+ c = uint(c^uint(0xffffffff));
+ png.position = e;
+ png.writeUnsignedInt(c);
+ }
+ }
}
\ No newline at end of file diff --git a/webcam/com/neave/media/NeaveCamera.as b/webcam/com/neave/media/NeaveCamera.as new file mode 100755 index 0000000..f401af8 --- /dev/null +++ b/webcam/com/neave/media/NeaveCamera.as @@ -0,0 +1,81 @@ +/**
+ * Neave Camera
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.media
+{
+ import flash.events.*;
+ import flash.media.*;
+ import flash.system.*;
+
+ public class NeaveCamera
+ {
+ /**
+ * The requested width of the camera object
+ */
+ static public var CAMERA_WIDTH:int = 320;
+
+ /**
+ * The requested height of the camera object
+ */
+ static public var CAMERA_HEIGHT:int = 240;
+
+ static private var cam:Camera;
+
+ public function NeaveCamera() { }
+
+ /**
+ * Sets up and returns the camera object
+ *
+ * @return A camera object
+ */
+ static public function getCamera():Camera
+ {
+ // Return the same camera if it has been successfully requested before
+ if (cam != null)
+ {
+ if (cam.muted) Security.showSettings(SecurityPanel.PRIVACY);
+ return cam;
+ }
+
+ // Get the camera
+ cam = Camera.getCamera();
+ if (cam != null)
+ {
+ // Set properties if a camera was found
+ cam.setMode(CAMERA_WIDTH, CAMERA_HEIGHT, 30, true);
+ cam.addEventListener(StatusEvent.STATUS, NeaveCamera.statusListener);
+ return cam;
+ }
+ else
+ {
+ // No camera found
+ Security.showSettings(SecurityPanel.CAMERA);
+ return new Camera();
+ }
+ }
+
+ /**
+ * Whether the camera object is available or not
+ */
+ static public function get muted():Boolean
+ {
+ return cam == null || cam.muted || cam.name == null || cam.width == 0;
+ }
+
+ /**
+ * Camera status response
+ */
+ static private function statusListener(e:StatusEvent):void
+ {
+ if (e.code == "Camera.Unmuted") Security.showSettings(SecurityPanel.CAMERA);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/media/NeaveMicrophone.as b/webcam/com/neave/media/NeaveMicrophone.as new file mode 100755 index 0000000..6a46ee7 --- /dev/null +++ b/webcam/com/neave/media/NeaveMicrophone.as @@ -0,0 +1,104 @@ +/**
+ * Neave Microphone
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.media
+{
+ import flash.events.*;
+ import flash.media.*;
+ import flash.system.*;
+ import flash.utils.*;
+
+ public class NeaveMicrophone
+ {
+ static private var mic:Microphone;
+ static private var gainTimer:Timer;
+
+ public function NeaveMicrophone() { }
+
+ /**
+ * Sets up and returns the microphone object
+ *
+ * @return A microphone object
+ */
+ static public function getMicrophone():Microphone
+ {
+ // Return the same microphone if it has been successfully requested before
+ if (mic != null)
+ {
+ if (mic.muted) Security.showSettings(SecurityPanel.PRIVACY);
+ else NeaveMicrophone.startAutoGain();
+ return mic;
+ }
+
+ gainTimer = new Timer(100);
+
+ // Get the microphone
+ mic = Microphone.getMicrophone();
+ if (mic != null)
+ {
+ // Set properties if a microphone was found
+ mic.setLoopBack(true);
+ mic.rate = 44;
+ mic.gain = 25;
+ mic.setSilenceLevel(0);
+ mic.setUseEchoSuppression(true);
+ mic.soundTransform = new SoundTransform(0); // Mute microphone from sounding on speakers
+ mic.addEventListener(StatusEvent.STATUS, NeaveMicrophone.statusListener);
+
+ return mic;
+ }
+ else
+ {
+ // No microphone found
+ Security.showSettings(SecurityPanel.MICROPHONE);
+ return new Microphone();
+ }
+ }
+
+ /**
+ * Microphone status response
+ */
+ static private function statusListener(e:StatusEvent):void
+ {
+ if (e.code == "Microphone.Unmuted") NeaveMicrophone.startAutoGain();
+ else NeaveMicrophone.stopAutoGain();
+ }
+
+ /**
+ * Set up gain control
+ */
+ static public function startAutoGain():void
+ {
+ gainTimer.start();
+ if (!gainTimer.hasEventListener(TimerEvent.TIMER)) gainTimer.addEventListener(TimerEvent.TIMER, setGain);
+ }
+
+ /**
+ * Stop gain control
+ */
+ static public function stopAutoGain():void
+ {
+ gainTimer.stop();
+ gainTimer.reset();
+ gainTimer.removeEventListener(TimerEvent.TIMER, setGain);
+ }
+
+ /**
+ * Dynamically adjust the microphone's gain value
+ */
+ static private function setGain(e:TimerEvent):void
+ {
+ if (mic.activityLevel < 15) mic.gain = 30;
+ else if (mic.activityLevel > 90) mic.gain = 20;
+ else mic.gain = 25;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/NeaveWebcam.as b/webcam/com/neave/webcam/NeaveWebcam.as new file mode 100755 index 0000000..5372ad5 --- /dev/null +++ b/webcam/com/neave/webcam/NeaveWebcam.as @@ -0,0 +1,198 @@ +/**
+ * Neave Webcam ...play with webcam effects
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * @author Paul Neave
+ * @version 1.0.0
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam
+{
+ import flash.display.*;
+ import flash.events.*;
+ import flash.media.*;
+ import flash.ui.*;
+ import com.neave.media.*;
+ import com.neave.webcam.effects.*;
+
+ public class NeaveWebcam extends Sprite
+ {
+ // Main variables
+ private var camera:Camera;
+ private var video:Video;
+ private var videoBitmap:Bitmap;
+ private var videoContainer:Sprite;
+ private var uiEnabled:Boolean;
+
+ /**
+ * Manages the webcam effects
+ */
+ public var effects:EffectsManager;
+
+ /**
+ * Creates a new instance of Neave Webcam
+ *
+ * @param camera The camera object to use to create the webcam effects
+ * @param interactive Enable mouse click or arrow keys to change the webcam effect
+ */
+ public function NeaveWebcam(camera:Camera, interactive:Boolean = true)
+ {
+ this.camera = camera;
+
+ initVideo();
+ initEffects();
+
+ this.interactive = interactive;
+ }
+
+ /**
+ * Sets up the main video object
+ */
+ private function initVideo():void
+ {
+ // Video dimensions must be 320x240 or higher
+ var w:int = camera.width < NeaveCamera.CAMERA_WIDTH ? NeaveCamera.CAMERA_WIDTH : camera.width;
+ var h:int = camera.height < NeaveCamera.CAMERA_HEIGHT ? NeaveCamera.CAMERA_HEIGHT : camera.height;
+
+ // Attach the camera object a video object
+ video = new Video(w, h);
+ video.attachCamera(camera);
+
+ // Create a bitmap object for the video effect, flipping to create a mirror image
+ videoBitmap = new Bitmap(new BitmapData(w, h, false, 0xFF000000), PixelSnapping.AUTO, false);
+ videoBitmap.scaleX = -1;
+ videoBitmap.x = w;
+
+ // Create a sprite to hold the bitmap
+ videoContainer = new Sprite();
+ videoContainer.addChild(videoBitmap);
+ videoContainer.scaleX = -1;
+ videoContainer.x = w;
+ addChild(videoContainer);
+ }
+
+ /**
+ * Sets up the webcam effects for the video object
+ */
+ private function initEffects():void
+ {
+ // Set up the effects manager for this video object
+ effects = new EffectsManager(video, videoBitmap.bitmapData);
+ paused = false;
+ }
+
+ /**
+ * Enable mouse click or arrow keys to change the webcam effect
+ */
+ public function set interactive(i:Boolean):void
+ {
+ uiEnabled = i;
+
+ if (uiEnabled)
+ {
+ // Arrow keys select previous or next webcam effect
+ addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
+
+ // Clicking on the video selects the next webcam effect
+ videoContainer.addEventListener(MouseEvent.CLICK, videoClickListener);
+ videoContainer.buttonMode = true;
+ }
+ else
+ {
+ // Remove interactivity
+ removeEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
+ videoContainer.removeEventListener(MouseEvent.CLICK, videoClickListener);
+ videoContainer.buttonMode = false;
+ }
+ }
+
+ /**
+ * Moves to the next webcam effect on mouse click
+ */
+ private function videoClickListener(e:MouseEvent):void
+ {
+ if (paused || camera.muted || camera.width == 0) return;
+
+ effects.nextEffect();
+ }
+
+ /**
+ * Moves to the next or previous webcam effect when the arrow keys are pressed
+ */
+ private function keyDownListener(e:KeyboardEvent):void
+ {
+ if (paused || camera.muted || camera.width == 0) return;
+
+ switch (e.keyCode)
+ {
+ case Keyboard.LEFT:
+ effects.previousEffect();
+ break;
+
+ case Keyboard.RIGHT:
+ effects.nextEffect();
+ break;
+ }
+ }
+
+ /**
+ * The bitmap data containing the current webcam effect
+ */
+ public function get effectBitmap():BitmapData
+ {
+ return videoBitmap.bitmapData;
+ }
+
+ /**
+ * Pause or resume the current webcam effect
+ */
+ public function set paused(p:Boolean):void
+ {
+ if (p == paused) return;
+
+ // Pause or resume updating the current webcam effect every frame
+ if (p) removeEventListener(Event.ENTER_FRAME, update);
+ else addEventListener(Event.ENTER_FRAME, update);
+ }
+
+ /**
+ * Pause or resume the current webcam effect
+ */
+ public function get paused():Boolean
+ {
+ return !hasEventListener(Event.ENTER_FRAME);
+ }
+
+ /**
+ * Removes the webcam and all other referenced objects
+ */
+ public function destroy():void
+ {
+ interactive = false;
+ paused = true;
+ effects.destroy();
+ videoContainer.removeChild(videoBitmap);
+ videoBitmap.bitmapData.dispose();
+ videoBitmap.bitmapData = null;
+ videoBitmap = null;
+ removeChild(videoContainer);
+ videoContainer = null;
+ video = null;
+ camera = null;
+ }
+
+ /**
+ * Updates the current webcam effect
+ */
+ private function update(e:Event):void
+ {
+ effects.update();
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/AbstractEffect.as b/webcam/com/neave/webcam/effects/AbstractEffect.as new file mode 100755 index 0000000..a0fb241 --- /dev/null +++ b/webcam/com/neave/webcam/effects/AbstractEffect.as @@ -0,0 +1,81 @@ +/**
+ * Neave Webcam // Abstract Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects
+{
+ import flash.display.*;
+ import flash.geom.*;
+
+ public class AbstractEffect
+ {
+ protected var source:IBitmapDrawable;
+ protected var targetBitmap:BitmapData;
+ protected var name:String;
+ protected var sourceBitmap:BitmapData;
+ protected var sourceMatrix:Matrix;
+ protected var rect:Rectangle;
+ protected var point:Point;
+ protected var color:ColorTransform;
+
+ /**
+ * An abstract effect class, not to be instantiated
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param name The proper name of the effect
+ */
+ public function AbstractEffect(source:IBitmapDrawable, targetBitmap:BitmapData, name:String = "")
+ {
+ this.source = source;
+ this.targetBitmap = targetBitmap;
+ this.name = name;
+
+ createEffect();
+ }
+
+ /**
+ * Sets up the effect
+ */
+ private function createEffect():void
+ {
+ sourceBitmap = targetBitmap.clone();
+ sourceMatrix = new Matrix();
+ rect = targetBitmap.rect;
+ point = new Point();
+ color = new ColorTransform();
+ }
+
+ /**
+ * The proper name of the effect
+ */
+ public function get effectName():String
+ {
+ return name;
+ }
+
+ /**
+ * Draws the effect
+ */
+ public function draw():void
+ {
+ sourceBitmap.draw(source, sourceMatrix, color);
+ }
+
+ /**
+ * Removes the effect and all other referenced objects
+ */
+ public function destroy():void
+ {
+ sourceBitmap.dispose();
+ sourceBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/EffectEvent.as b/webcam/com/neave/webcam/effects/EffectEvent.as new file mode 100755 index 0000000..134b792 --- /dev/null +++ b/webcam/com/neave/webcam/effects/EffectEvent.as @@ -0,0 +1,23 @@ +package com.neave.webcam.effects
+{
+ import flash.events.*;
+
+ public class EffectEvent extends Event
+ {
+ public static const NEW_EFFECT:String = "newEffect";
+
+ private var _effectType:int;
+
+ public function EffectEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, effectType:int = 0)
+ {
+ super(type, bubbles, cancelable);
+
+ _effectType = effectType;
+ }
+
+ public function get effectType():int
+ {
+ return _effectType;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/EffectType.as b/webcam/com/neave/webcam/effects/EffectType.as new file mode 100755 index 0000000..3c9967d --- /dev/null +++ b/webcam/com/neave/webcam/effects/EffectType.as @@ -0,0 +1 @@ +/**
* Neave Webcam // Effects Type
*
* Copyright (C) 2008 Paul Neave
* http://www.neave.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
*/
package com.neave.webcam.effects
{
final public class EffectType
{
/*static public const NORMAL :int = 0;
static public const RAINBOW :int = 1;
//static public const MIRROR_RIGHT :int = 2;
//static public const MIRROR_TOP :int = 3;
//static public const MIRROR_BOTTOM :int = 2;
static public const MIRROR_INVERSE :int = 2;
//static public const MIRROR_QUAD :int = 6;
static public const UPSIDE_DOWN :int = 3;
//static public const DIVIDE :int = 8;
//static public const FILMSTRIP :int = 9;
static public const FRAGMENT :int = 4;
static public const SEPIA :int = 5;
//static public const TRAIL :int = 12;
//static public const BULGE :int = 13;
//static public const FISHEYE :int = 14;
//static public const FISHBOWL :int = 15;
//static public const DENT :int = 16;
///static public const SQUEEZE :int = 17;
static public const WATER :int = 6;
static public const FIRE :int = 7;
static public const SNOW :int = 8;
//static public const STEAM :int = 21;
static public const SWARM :int = 9;
//static public const PIXELATE :int = 23;
//static public const RGB :int = 24;
//static public const HALFTONE :int = 25;
static public const MONOCHROME :int = 10;
static public const GHOST :int = 11;
static public const MIRROR_LEFT :int = 12;
//static public const ASCII :int = 14;
//static public const X_RAY :int = 30;
//static public const WARHOL :int = 31;
static public const GLOW :int = 13;
static public const SLIT_SCAN :int = 14;*/
static public const NORMAL :int = 0;
static public const GLOW :int = 1;
static public const WARHOL :int = 2;
static public const HALFTONE :int = 3;
static public const SEPIA :int = 4;
static public const MONOCHROME :int = 5;
static public const X_RAY :int = 6;
static public const DIVIDE :int = 7;
static public const SLIT_SCAN :int = 8;
static public const MIRROR_INVERSE :int = 9;
static public const MIRROR_TOP :int = 10;
static public const UPSIDE_DOWN :int = 11;
static public const MIRROR_LEFT :int = 12;
static public const BULGE :int = 13;
static public const SQUEEZE :int = 14;
static public const FISHEYE :int = 15;
static public const GHOST :int = 16;
static public const TRAIL :int = 17;
static public const WATER :int = 18;
static public const SNOW :int = 19;
static public const FIRE :int = 20;
static public const SWARM :int = 21;
static public const TOTAL_EFFECTS :int = 21;
public function EffectType() { }
}
}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/EffectsManager.as b/webcam/com/neave/webcam/effects/EffectsManager.as new file mode 100755 index 0000000..0c898c8 --- /dev/null +++ b/webcam/com/neave/webcam/effects/EffectsManager.as @@ -0,0 +1 @@ +/**
* Neave Webcam // Effects Manager
*
* Copyright (C) 2008 Paul Neave
* http://www.neave.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
*/
package com.neave.webcam.effects
{
import flash.display.*;
import flash.events.*;
import com.neave.webcam.effects.color.*;
import com.neave.webcam.effects.delay.*;
import com.neave.webcam.effects.displace.*;
import com.neave.webcam.effects.mirror.*;
import com.neave.webcam.effects.motion.*;
import com.neave.webcam.effects.pixel.*;
public class EffectsManager extends EventDispatcher
{
private var source:IBitmapDrawable;
private var targetBitmap:BitmapData;
private var effect:AbstractEffect;
private var chosenEffect:int;
/**
* Manages all of the webcam effects
*
* @param source The source object to use for the effect
* @param targetBitmap The target bitmap data to draw the resulting effect into
*/
public function EffectsManager(source:IBitmapDrawable, targetBitmap:BitmapData)
{
this.source = source;
this.targetBitmap = targetBitmap;
// Start with the normal effect
effectType = EffectType.NORMAL;
}
/**
* Sets the effect to the next effect in the EffectType class
*/
public function nextEffect():void
{
effectType = chosenEffect + 1;
}
/**
* Sets the effect to the previous effect in the EffectType class
*/
public function previousEffect():void
{
effectType = chosenEffect - 1;
}
/**
* An integer representing the current effect in the EffectType class
*/
public function set effectType(type:int):void
{
// Remove the previous effect
if (effect != null) effect.destroy();
// Wrap the chosen effect within the total effects available
if (type > EffectType.TOTAL_EFFECTS) type = 0;
if (type < 0) type = EffectType.TOTAL_EFFECTS;
// Set the effect
switch (type)
{
case EffectType.GLOW: effect = new GlowEffect (source, targetBitmap); break;
case EffectType.WARHOL: effect = new WarholEffect (source, targetBitmap); break;
case EffectType.SEPIA: effect = new SepiaEffect (source, targetBitmap); break;
case EffectType.MONOCHROME: effect = new MonochromeEffect (source, targetBitmap); break;
case EffectType.X_RAY: effect = new XRayEffect (source, targetBitmap); break;
case EffectType.DIVIDE: effect = new DivideEffect (source, targetBitmap); break;
case EffectType.SLIT_SCAN: effect = new SlitScanEffect (source, targetBitmap); break;
case EffectType.MIRROR_INVERSE: effect = new InverseMirrorEffect (source, targetBitmap); break;
case EffectType.MIRROR_TOP: effect = new TopMirrorEffect (source, targetBitmap); break;
case EffectType.UPSIDE_DOWN: effect = new UpsideDownEffect (source, targetBitmap); break;
case EffectType.MIRROR_LEFT: effect = new LeftMirrorEffect (source, targetBitmap); break;
case EffectType.BULGE: effect = new BulgeEffect (source, targetBitmap); break;
case EffectType.SQUEEZE: effect = new SqueezeEffect (source, targetBitmap); break;
case EffectType.FISHEYE: effect = new FisheyeEffect (source, targetBitmap); break;
case EffectType.GHOST: effect = new GhostEffect (source, targetBitmap); break;
case EffectType.TRAIL: effect = new TrailEffect (source, targetBitmap); break;
case EffectType.WATER: effect = new WaterEffect (source, targetBitmap); break;
case EffectType.SNOW: effect = new SnowEffect (source, targetBitmap); break;
case EffectType.FIRE: effect = new FireEffect (source, targetBitmap); break;
case EffectType.SWARM: effect = new SwarmEffect (source, targetBitmap); break;
/*case EffectType.MIRROR_LEFT: effect = new LeftMirrorEffect (source, targetBitmap); break;
//case EffectType.MIRROR_RIGHT: effect = new RightMirrorEffect (source, targetBitmap); break;
//case EffectType.MIRROR_TOP: effect = new TopMirrorEffect (source, targetBitmap); break;
//case EffectType.MIRROR_BOTTOM: effect = new BottomMirrorEffect (source, targetBitmap); break;
case EffectType.MIRROR_INVERSE: effect = new InverseMirrorEffect (source, targetBitmap); break;
//case EffectType.MIRROR_QUAD: effect = new QuadMirrorEffect (source, targetBitmap); break;
case EffectType.UPSIDE_DOWN: effect = new UpsideDownEffect (source, targetBitmap); break;
//case EffectType.DIVIDE: effect = new DivideEffect (source, targetBitmap); break;
//case EffectType.FILMSTRIP: effect = new FilmstripEffect (source, targetBitmap); break;
case EffectType.FRAGMENT: effect = new FragmentEffect (source, targetBitmap); break;
case EffectType.GHOST: effect = new GhostEffect (source, targetBitmap); break;
//case EffectType.TRAIL: effect = new TrailEffect (source, targetBitmap); break;
//case EffectType.BULGE: effect = new BulgeEffect (source, targetBitmap); break;
//case EffectType.FISHEYE: effect = new FisheyeEffect (source, targetBitmap); break;
//case EffectType.FISHBOWL: effect = new FishbowlEffect (source, targetBitmap); break;
//case EffectType.DENT: effect = new DentEffect (source, targetBitmap); break;
//case EffectType.SQUEEZE: effect = new SqueezeEffect (source, targetBitmap); break;
case EffectType.WATER: effect = new WaterEffect (source, targetBitmap); break;
case EffectType.FIRE: effect = new FireEffect (source, targetBitmap); break;
case EffectType.SNOW: effect = new SnowEffect (source, targetBitmap); break;
//case EffectType.STEAM: effect = new SteamEffect (source, targetBitmap); break;
case EffectType.SWARM: effect = new SwarmEffect (source, targetBitmap); break;
//case EffectType.PIXELATE: effect = new PixelateEffect (source, targetBitmap); break;
//case EffectType.RGB: effect = new RGBEffect (source, targetBitmap); break;
//case EffectType.HALFTONE: effect = new HalftoneEffect (source, targetBitmap); break;
case EffectType.MONOCHROME: effect = new MonochromeEffect (source, targetBitmap); break;
case EffectType.SEPIA: effect = new SepiaEffect (source, targetBitmap); break;
case EffectType.RAINBOW: effect = new RainbowEffect (source, targetBitmap); break;
//case EffectType.ASCII: effect = new ASCIIEffect (source, targetBitmap); break;
//case EffectType.X_RAY: effect = new XRayEffect (source, targetBitmap); break;
//case EffectType.WARHOL: effect = new WarholEffect (source, targetBitmap); break;
case EffectType.GLOW: effect = new GlowEffect (source, targetBitmap); break;
case EffectType.SLIT_SCAN: effect = new SlitScanEffect (source, targetBitmap); break;*/
case EffectType.NORMAL:
default:
// Use a normal effect if the passed effect type is not valid
type = EffectType.NORMAL;
effect = new NormalEffect(source, targetBitmap);
break;
}
// Remember the chosen effect
chosenEffect = type;
// Tell anything listening that a new effect has been chosen
dispatchEvent(new EffectEvent(EffectEvent.NEW_EFFECT, false, false, chosenEffect));
}
/**
* An integer representing the current effect in the EffectType class
*/
public function get effectType():int
{
return chosenEffect;
}
/**
* The proper name of the current effect
*/
public function get effectName():String
{
return effect.effectName;
}
/**
* Updates the appearance of the current effect
*/
public function update():void
{
effect.draw();
}
/**
* Removes the current effect
*/
public function destroy():void
{
effect.destroy();
}
}
}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/NormalEffect.as b/webcam/com/neave/webcam/effects/NormalEffect.as new file mode 100755 index 0000000..b97e896 --- /dev/null +++ b/webcam/com/neave/webcam/effects/NormalEffect.as @@ -0,0 +1,38 @@ +/**
+ * Neave Webcam // Normal Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects
+{
+ import flash.display.*;
+
+ public class NormalEffect extends AbstractEffect
+ {
+ /**
+ * Creates a normal effect for copying the source object into the target bitmap data without modification
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function NormalEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Normal");
+ }
+
+ /**
+ * Draws the normal effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/color/GlowEffect.as b/webcam/com/neave/webcam/effects/color/GlowEffect.as new file mode 100755 index 0000000..5c96e71 --- /dev/null +++ b/webcam/com/neave/webcam/effects/color/GlowEffect.as @@ -0,0 +1,68 @@ +/**
+ * Neave Webcam // Glow Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class GlowEffect extends AbstractEffect
+ {
+ private var edge:ConvolutionFilter;
+ private var blur:BlurFilter;
+
+ /**
+ * Creates a high constrast glow effect around surface edges
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function GlowEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Glow");
+
+ createGlow();
+ }
+
+ /**
+ * Sets up the glow effect
+ */
+ private function createGlow():void
+ {
+ // Increase contrast
+ color = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Set up a large horizontal edge convoluton filter
+ var m:Array =
+ [
+ -100, -100, -100,
+ 100, 100, 100,
+ 0, 0, 0
+ ];
+ edge = new ConvolutionFilter(3, 3, m, 9);
+
+ // Blur the edges to create a smooth glow
+ blur = new BlurFilter(8, 8, 2);
+ }
+
+ /**
+ * Draws the glow effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ sourceBitmap.applyFilter(sourceBitmap, rect, point, blur);
+ targetBitmap.applyFilter(sourceBitmap, rect, point, edge);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/color/MonochromeEffect.as b/webcam/com/neave/webcam/effects/color/MonochromeEffect.as new file mode 100755 index 0000000..ed14de9 --- /dev/null +++ b/webcam/com/neave/webcam/effects/color/MonochromeEffect.as @@ -0,0 +1,61 @@ +/**
+ * Neave Webcam // Monochrome (Black & White) Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class MonochromeEffect extends AbstractEffect
+ {
+ private var monochrome:ColorMatrixFilter;
+
+ /**
+ * Creates a high contrast black and white monochrome effect
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function MonochromeEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Black & White");
+
+ createMonochrome();
+ }
+
+ /**
+ * Sets up the monochrome effect
+ */
+ private function createMonochrome():void
+ {
+ // Add punch with more contrast
+ color = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Monochrome colour matrix
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Red
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Green
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ monochrome = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the monochrome effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.applyFilter(sourceBitmap, rect, point, monochrome);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/color/RainbowEffect.as b/webcam/com/neave/webcam/effects/color/RainbowEffect.as new file mode 100755 index 0000000..3b5b70b --- /dev/null +++ b/webcam/com/neave/webcam/effects/color/RainbowEffect.as @@ -0,0 +1,90 @@ +/**
+ * Neave Webcam // Rainbow Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class RainbowEffect extends AbstractEffect
+ {
+ private var red:Array;
+ private var green:Array;
+ private var blue:Array;
+
+ /**
+ * Creates a psychedelic colour-cycling effect
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function RainbowEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Rainbow");
+
+ createRainbow();
+ }
+
+ /**
+ * Sets up the rainbow effect
+ */
+ private function createRainbow():void
+ {
+ // Add punch with more contrast
+ color = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Set up colour arrays
+ red = new Array(256);
+ green = new Array(256);
+ blue = new Array(256);
+
+ // Populate colour arrays with a curved gradient
+ for (var i:int = 0; i < 256; i++)
+ {
+ red[i] = Math.sin(i / 0xFF * Math.PI) * 0xFF << 16;
+ green[i] = Math.sin(i / 0xFF * Math.PI) * 0xFF << 8;
+ blue[i] = Math.sin(i / 0xFF * Math.PI) * 0xFF;
+ }
+ }
+
+ /**
+ * Draws the rainbow effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ red.push(red.splice(0, 1));
+ green.unshift(green.pop());
+ green.unshift(green.pop());
+ if (Math.random() < 0.5) green.unshift(green.pop());
+ blue.unshift(blue.pop());
+ blue.unshift(blue.pop());
+ blue.unshift(blue.pop());
+ if (Math.random() < 0.5) blue.unshift(blue.pop());
+ if (Math.random() < 0.5) blue.unshift(blue.pop());
+
+ targetBitmap.paletteMap(sourceBitmap, rect, point, red, green, blue);
+ }
+
+ /**
+ * Removes the rainbow effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ red = null;
+ green = null;
+ blue = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/color/SepiaDirt.as b/webcam/com/neave/webcam/effects/color/SepiaDirt.as new file mode 100755 index 0000000..4b03f65 --- /dev/null +++ b/webcam/com/neave/webcam/effects/color/SepiaDirt.as @@ -0,0 +1,31 @@ +/**
+ * Neave Webcam // Sepia Dirt
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+
+ final internal class SepiaDirt extends Shape
+ {
+ /**
+ * Creates a black circular shape to be used with the sepia effect
+ *
+ * @param x The position of the dirt on the x-axis
+ * @param y The position of the dirt on the y-axis
+ * @param radius The radius of the dirt
+ */
+ public function SepiaDirt(x:Number = 0, y:Number = 0, radius:Number = 1)
+ {
+ graphics.beginFill(0x000000);
+ graphics.drawCircle(x, y, radius);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/color/SepiaEffect.as b/webcam/com/neave/webcam/effects/color/SepiaEffect.as new file mode 100755 index 0000000..f7d2ebe --- /dev/null +++ b/webcam/com/neave/webcam/effects/color/SepiaEffect.as @@ -0,0 +1,90 @@ +/**
+ * Neave Webcam // Sepia Movie Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class SepiaEffect extends AbstractEffect
+ {
+ private var frameStep:int;
+ private var sepia:ColorMatrixFilter;
+ private var count:uint;
+ private var linePos:Number;
+
+ /**
+ * Creates an animated sepia effect like an old projector movie
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param frameStep The number of frames to step over to create a jittery movie effect
+ */
+ public function SepiaEffect(source:IBitmapDrawable, targetBitmap:BitmapData, frameStep:int = 3)
+ {
+ super(source, targetBitmap, "Sepia Movie");
+ this.frameStep = frameStep < 1 ? 1 : frameStep;
+
+ createSepia();
+ }
+
+ /**
+ * Sets up the sepia effect
+ */
+ private function createSepia():void
+ {
+ // Reset variables
+ count = linePos = 0;
+
+ // Sepia colour matrix
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Red
+ m = m.concat([0.246, 0.4838, 0.0902, 0, 10]); // Green
+ m = m.concat([0.15, 0.295, 0.055, 0, 10]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ sepia = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the sepia effect
+ */
+ override public function draw():void
+ {
+ if (count == 0)
+ {
+ super.draw();
+
+ // Tint source bitmap sepia
+ sourceBitmap.applyFilter(sourceBitmap, rect, point, sepia);
+
+ // Create old movie style black vertical line on one side
+ linePos += (Math.random() * rect.width * 0.25 - linePos) * 0.04;
+ if (Math.random() < 0.05) linePos = rect.width;
+ if (Math.random() < 0.05) linePos = rect.width * 0.2;
+ if (Math.random() < 0.5) sourceBitmap.fillRect(new Rectangle(Math.round(linePos), 0, 1, rect.height), 0xFF000000);
+
+ // Create random dirt with one big spot every so often
+ for (var i:int = 4; i--; ) sourceBitmap.draw(new SepiaDirt(Math.random() * rect.width, Math.random() * rect.height, Math.random() < 0.995 ? Math.random() + 0.5 : Math.random() * 10 + 15));
+
+ // Draw source bitmap into target bitmap with a slight flicker
+ var mult:uint = Math.random() * 64 + (255 - 64);
+ targetBitmap.lock();
+ targetBitmap.fillRect(rect, 0xFF000000);
+ targetBitmap.merge(sourceBitmap, rect, point, mult, mult, mult, 0);
+ targetBitmap.unlock();
+ }
+ count++;
+ count %= frameStep;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/color/WarholEffect.as b/webcam/com/neave/webcam/effects/color/WarholEffect.as new file mode 100755 index 0000000..81f8289 --- /dev/null +++ b/webcam/com/neave/webcam/effects/color/WarholEffect.as @@ -0,0 +1,99 @@ +/**
+ * Neave Webcam // Andy Warhol Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class WarholEffect extends AbstractEffect
+ {
+ private var smallBitmap:BitmapData;
+ private var pos1:Point;
+ private var pos2:Point;
+ private var pos3:Point;
+ private var pos4:Point;
+
+ /**
+ * Creates an Andy Warhol-style Pop Art effect with four highly constrasted tricolour images
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function WarholEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Andy Warhol");
+
+ createWarhol();
+ }
+
+ /**
+ * Sets up the Warhol effect
+ */
+ private function createWarhol():void
+ {
+ // Create a bitmap quarter the size of the original
+ smallBitmap = new BitmapData(Math.round(rect.width / 2), Math.round(rect.height / 2), false, 0xFF000000);
+ sourceMatrix.scale(0.5, 0.5);
+
+ // Positions of each image
+ pos1 = new Point(0, 0);
+ pos2 = new Point(smallBitmap.width, 0);
+ pos3 = new Point(0, smallBitmap.height);
+ pos4 = new Point(smallBitmap.width, smallBitmap.height);
+ }
+
+ /**
+ * Draws a tricolour (three colour) image from the passed bitmap into the target bitmap data
+ *
+ * @param bitmapData The source bitmap data to draw the tricolour from
+ * @param pos The position to draw tricolour
+ * @param color1 The background colour
+ * @param color2 The middle colour
+ * @param color3 The highlight colour
+ */
+ private function drawTricolor(bitmapData:BitmapData, pos:Point, color1:uint, color2:uint, color3:uint):void
+ {
+ // Limit the pixels in the bitmap data to three colours only
+ targetBitmap.threshold(bitmapData, rect, pos, "<=", 0xFFAAAAAA, color2);
+ targetBitmap.threshold(bitmapData, rect, pos, ">", 0xFFAAAAAA, color3);
+ targetBitmap.threshold(bitmapData, rect, pos, "<", 0xFF555555, color1);
+ }
+
+ /**
+ * Draws the Warhol effect
+ */
+ override public function draw():void
+ {
+ smallBitmap.draw(source, sourceMatrix);
+
+ targetBitmap.lock();
+ drawTricolor(smallBitmap, pos1, 0xFF0080FF, 0xFFFFFF00, 0xFFFF0080);
+ drawTricolor(smallBitmap, pos2, 0xFF202020, 0xFFFF0000, 0xFFFFFFFF);
+ drawTricolor(smallBitmap, pos3, 0xFFA040A0, 0xFFFF9900, 0xFF80C0FF);
+ drawTricolor(smallBitmap, pos4, 0xFF40A000, 0xFFFFFFA0, 0xFFFFA0FF);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the Warhol effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ smallBitmap.dispose();
+ smallBitmap = null;
+ pos1 = pos2 = pos3 = pos4 = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/color/XRayEffect.as b/webcam/com/neave/webcam/effects/color/XRayEffect.as new file mode 100755 index 0000000..06067bd --- /dev/null +++ b/webcam/com/neave/webcam/effects/color/XRayEffect.as @@ -0,0 +1,62 @@ +/**
+ * Neave Webcam // X-Ray Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class XRayEffect extends AbstractEffect
+ {
+ private var cyanWash:ColorMatrixFilter;
+
+ /**
+ * Creates a mock x-ray effect by inverting the image
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function XRayEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "X-Ray");
+
+ createXRay();
+ }
+
+ /**
+ * Sets up the x-ray effect
+ */
+ private function createXRay():void
+ {
+ // Invert the image
+ color = new ColorTransform(-1.5, -1.5, -1.5, 1, 0xFF, 0xFF, 0xFF);
+
+ // Monochrome colour matrix with a cyan tint
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Red
+ m = m.concat([0.3, 0.59, 0.11, 0, 40]); // Green
+ m = m.concat([0.3, 0.59, 0.11, 0, 50]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ cyanWash = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the x-ray effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.applyFilter(sourceBitmap, rect, point, cyanWash);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/delay/DivideEffect.as b/webcam/com/neave/webcam/effects/delay/DivideEffect.as new file mode 100755 index 0000000..5e9cfee --- /dev/null +++ b/webcam/com/neave/webcam/effects/delay/DivideEffect.as @@ -0,0 +1,99 @@ +/**
+ * Neave Webcam // Delayed Divide Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class DivideEffect extends AbstractEffect
+ {
+ private var frames:int;
+ private var divideBitmaps:Array;
+ private var divideRect:Rectangle;
+ private var dividePoint:Point;
+
+ /**
+ * Creates a split screen effect where the lower half of the image is delayed
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param frames The number of frames to delay the lower half of the image by
+ */
+ public function DivideEffect(source:IBitmapDrawable, targetBitmap:BitmapData, frames:int = 30)
+ {
+ super(source, targetBitmap, "Delayed Divide");
+ this.frames = frames < 2 ? 2 : frames;
+
+ createDivide();
+ }
+
+ /**
+ * Sets up the divide effect
+ */
+ private function createDivide():void
+ {
+ // Define the lower half area and its top left position
+ divideRect = new Rectangle(0, rect.height / 2, rect.width, rect.height / 2);
+ dividePoint = new Point(0, rect.height / 2);
+
+ // Draw the delayed bitmap into the lower half
+ var m:Matrix = sourceMatrix.clone();
+ m.translate(0, -rect.height / 2);
+
+ // Create an array of bitmaps to store the delayed frames
+ divideBitmaps = new Array();
+ for (var i:int = frames; i--; )
+ {
+ var b:BitmapData = new BitmapData(rect.width, rect.height / 2, false, 0xFF000000);
+ b.draw(source, m, color, null, rect, true); // Start with the current source image
+ divideBitmaps.push(b);
+ }
+ }
+
+ /**
+ * Draws the divide effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through all the delayed frames
+ for (var i:int = frames; i--; )
+ {
+ var b:BitmapData = divideBitmaps[i];
+ if (i == 0) b.copyPixels(sourceBitmap, divideRect, point); // Draw the current source image into frame 0
+ else b.copyPixels(divideBitmaps[i - 1], b.rect, point); // Move the other frames along the array
+ }
+
+ // Draw the final delayed frame into the lower half with the current source image
+ sourceBitmap.copyPixels(divideBitmaps[frames - 1], divideBitmaps[0].rect, dividePoint);
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ }
+
+ /**
+ * Removes the divide effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the frame bitmaps
+ for (var i:int = frames; i--; )
+ {
+ divideBitmaps[i].dispose();
+ divideBitmaps[i] = null;
+ }
+ divideBitmaps = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/delay/FilmstripEffect.as b/webcam/com/neave/webcam/effects/delay/FilmstripEffect.as new file mode 100755 index 0000000..ce324b1 --- /dev/null +++ b/webcam/com/neave/webcam/effects/delay/FilmstripEffect.as @@ -0,0 +1,91 @@ +/**
+ * Neave Webcam // Filmstrip Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class FilmstripEffect extends AbstractEffect
+ {
+ private var scale:int;
+ private var total:int;
+ private var filmstrip:Array;
+
+ /**
+ * Creates a grid of delayed images, each delayed by one frame after the previous frame
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param scale The number of images to use along the width and height of the grid
+ */
+ public function FilmstripEffect(source:IBitmapDrawable, targetBitmap:BitmapData, scale:int = 8)
+ {
+ super(source, targetBitmap, "Filmstrip");
+ this.scale = scale < 2 ? 2 : scale;
+
+ createFilmstrip();
+ }
+
+ /**
+ * Sets up the filmstrip effect
+ */
+ private function createFilmstrip():void
+ {
+ // Resize the source to the set scale
+ sourceMatrix.scale(1 / scale, 1 / scale);
+
+ // Create an array of bitmaps to store the delayed frames
+ total = scale * scale;
+ filmstrip = new Array();
+ for (var i:int = total; i--; )
+ {
+ var b:BitmapData = new BitmapData(rect.width / scale, rect.height / scale, false, 0xFF000000);
+ b.draw(source, sourceMatrix, color, null, null, true);
+ filmstrip.push(b);
+ }
+ }
+
+ /**
+ * Draws the filmstrip effect
+ */
+ override public function draw():void
+ {
+ // Loop through all the delayed frames
+ targetBitmap.lock();
+ for (var i:int = total; i--; )
+ {
+ var b:BitmapData = filmstrip[i];
+ if (i == 0) b.draw(source, sourceMatrix, color); // Draw the source at a smaller size into frame 0
+ else b.copyPixels(filmstrip[i - 1], b.rect, point); // Move the other frames along the array
+ targetBitmap.copyPixels(b, b.rect, new Point((scale - (i % scale) - 1) * rect.width / scale, int(i / scale) * rect.height / scale)); // Draw this frame in position
+ }
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the divide effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the filmstrip bitmaps
+ for (var i:int = total; i--; )
+ {
+ filmstrip[i].dispose();
+ filmstrip[i] = null;
+ }
+ filmstrip = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/delay/GhostEffect.as b/webcam/com/neave/webcam/effects/delay/GhostEffect.as new file mode 100755 index 0000000..35c5787 --- /dev/null +++ b/webcam/com/neave/webcam/effects/delay/GhostEffect.as @@ -0,0 +1,89 @@ +/**
+ * Neave Webcam // Ghost Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class GhostEffect extends AbstractEffect
+ {
+ private var frames:int;
+ private var ghostBitmaps:Array;
+
+ /**
+ * Creates a ghost effect where the source image is delayed then blended with the current image
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param frames The number of frames to delay the ghost image by
+ */
+ public function GhostEffect(source:IBitmapDrawable, targetBitmap:BitmapData, frames:int = 30)
+ {
+ super(source, targetBitmap, "Ghost");
+ this.frames = frames < 2 ? 2 : frames;
+
+ createGhost();
+ }
+
+ /**
+ * Sets up the ghost effect
+ */
+ private function createGhost():void
+ {
+ // Create an array of bitmaps to store the delayed frames
+ ghostBitmaps = new Array();
+ for (var i:int = frames; i--; )
+ {
+ var b:BitmapData = sourceBitmap.clone();
+ b.draw(source, null, color, null, null, true); // Start with the current source image
+ ghostBitmaps.push(b);
+ }
+ }
+
+ /**
+ * Draws the ghost effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through all the delayed frames
+ for (var i:int = frames; i--; )
+ {
+ var b:BitmapData = ghostBitmaps[i];
+ if (i == 0) b.copyPixels(sourceBitmap, rect, point); // Draw the current source image into frame 0
+ else b.copyPixels(ghostBitmaps[i - 1], rect, point); // Move the other frames along the array
+ }
+
+ // Blend the final delayed frame with the current source image
+ sourceBitmap.merge(ghostBitmaps[frames - 1], rect, point, 128, 128, 128, 0);
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ }
+
+ /**
+ * Removes the ghost effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the frame bitmaps
+ for (var i:int = frames; i--; )
+ {
+ ghostBitmaps[i].dispose();
+ ghostBitmaps[i] = null;
+ }
+ ghostBitmaps = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/delay/SlitScanEffect.as b/webcam/com/neave/webcam/effects/delay/SlitScanEffect.as new file mode 100755 index 0000000..37eb00c --- /dev/null +++ b/webcam/com/neave/webcam/effects/delay/SlitScanEffect.as @@ -0,0 +1,178 @@ +/**
+ * Neave Webcam // Slit Scan Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class SlitScanEffect extends AbstractEffect
+ {
+ private const MAX_SLITS:int = 60;
+
+ private var slitHeight:int;
+ private var slitScale:Number;
+ private var initScale:Number;
+ private var total:int;
+ private var slitBitmaps:Array;
+ private var slitMatrix:Matrix;
+ private var slitRect:Rectangle;
+ private var halfBitmap:BitmapData;
+ private var topMatrix:Matrix;
+ private var bottomPoint:Point;
+ private var moveUp:Boolean;
+ private var midX:Number;
+
+ /**
+ * Creates a slit scan effect, similar to the final scene in 2001: A Space Odyssey
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param slitHeight The height of the slit to capture in pixels
+ * @param slitScale How much to increase the size of each slit by
+ * @param initScale The scale of the first slit
+ */
+ public function SlitScanEffect(source:IBitmapDrawable, targetBitmap:BitmapData, slitHeight:int = 1, slitScale:Number = 1.125, initScale:Number = 0.25)
+ {
+ super(source, targetBitmap, "Slit Scan");
+ this.slitHeight = slitHeight < 1 ? 1 : slitHeight;
+ this.slitScale = slitScale < 0.1 ? 0.1 : slitScale;
+ this.initScale = initScale < 0.1 ? 0.1 : initScale;
+
+ createSlitScan();
+ }
+
+ /**
+ * Sets up the slit scan effect
+ */
+ private function createSlitScan():void
+ {
+ // Slit dimensions
+ slitMatrix = new Matrix();
+ slitRect = new Rectangle(0, 0, rect.width, slitHeight);
+
+ // Create a half-sized bitmap to contain all the slit scans
+ halfBitmap = new BitmapData(rect.width, Math.round(rect.height / 2), false, 0xFF000000);
+ topMatrix = new Matrix(1, 0, 0, -1, 0, halfBitmap.height);
+ bottomPoint = new Point(0, halfBitmap.height);
+
+ // Create an array of bitmaps to store the slits
+ slitBitmaps = new Array();
+ setTotal();
+ for (var i:int = total; i--; )
+ {
+ var b:BitmapData = new BitmapData(rect.width, slitHeight, false, 0xFF000000);
+ b.draw(source, null, color, null, slitRect, true); // Start with the current source image
+ slitBitmaps.push(b);
+ }
+
+ // Other variables
+ moveUp = false;
+ midX = rect.width / 2 / initScale - rect.width / 2;
+ }
+
+ /**
+ * Calculates the total number of slits needed to cover the half-sized bitmap
+ */
+ private function setTotal():void
+ {
+ total = 0;
+ var size:Number = slitHeight * initScale;
+ var lastSize:Number = size;
+
+ // Loop through the slit sizes, increasing in height until the size is bigger than the bitmap height
+ while (size < halfBitmap.height && total < MAX_SLITS)
+ {
+ var nextSize:Number = lastSize * slitScale;
+ lastSize = nextSize;
+ size += nextSize;
+ total++;
+ }
+ }
+
+ /**
+ * Moves the slit position up or down the source image
+ */
+ private function moveSlit():void
+ {
+ if (moveUp)
+ {
+ // Moving up or reversing direction
+ if (slitRect.top > 1) slitRect.offset(0, -slitHeight);
+ else moveUp = false;
+ }
+ else
+ {
+ // Moving down or reversing direction
+ if (slitRect.top < rect.height - slitHeight - 1) slitRect.offset(0, slitHeight);
+ else moveUp = true;
+ }
+ }
+
+ /**
+ * Draw the slit scan effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Move the slit up or down
+ moveSlit();
+
+ // Set slit to initial position and size
+ slitMatrix.identity();
+ slitMatrix.tx = midX;
+ slitMatrix.scale(initScale, initScale);
+
+ // Draw each slit
+ for (var i:int = total; i--; )
+ {
+ // Draw or move each slit along the array
+ var b:BitmapData = slitBitmaps[i];
+ if (i == 0) b.copyPixels(sourceBitmap, slitRect, point); // Draw the current source image into slit 0
+ else b.copyPixels(slitBitmaps[i - 1], b.rect, point); // Move the other slits along the array
+
+ // Scale each slit up and position in the middle
+ slitMatrix.scale(slitScale, slitScale);
+ slitMatrix.translate(rect.width / 2 * (1 - slitScale), slitHeight * initScale);
+
+ // Draw this new slit into the main half-size bitmap
+ halfBitmap.draw(slitBitmaps[total - i - 1], slitMatrix, null, null, null, true);
+ }
+
+ // Draw the half-size bitmaps into the top and bottom
+ targetBitmap.lock();
+ targetBitmap.draw(halfBitmap, topMatrix);
+ targetBitmap.copyPixels(halfBitmap, halfBitmap.rect, bottomPoint);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the slit scan effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the frame bitmaps
+ for (var i:int = total; i--; )
+ {
+ slitBitmaps[i].dispose();
+ slitBitmaps[i] = null;
+ }
+ slitBitmaps = null;
+
+ halfBitmap.dispose();
+ halfBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/delay/TrailEffect.as b/webcam/com/neave/webcam/effects/delay/TrailEffect.as new file mode 100755 index 0000000..41a9c91 --- /dev/null +++ b/webcam/com/neave/webcam/effects/delay/TrailEffect.as @@ -0,0 +1,68 @@ +/**
+ * Neave Webcam // Trail Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import com.neave.webcam.effects.*;
+
+ public class TrailEffect extends AbstractEffect
+ {
+ private var fade:uint;
+ private var whiteBitmap:BitmapData;
+
+ /**
+ * Creates a trail effect by smearing and fading out movement
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param fade The amount to fade out the trail by each frame, the higher the faster
+ */
+ public function TrailEffect(source:IBitmapDrawable, targetBitmap:BitmapData, fade:uint = 8)
+ {
+ super(source, targetBitmap, "Trail");
+ this.fade = fade > 0xFF ? 0xFF: fade;
+
+ createTrail();
+ }
+
+ /**
+ * Sets up the trail effect
+ */
+ private function createTrail():void
+ {
+ whiteBitmap = new BitmapData(rect.width, rect.height, false, 0xFFFFFFFF); // White bitmap for fading out the trail
+ targetBitmap.draw(source, null, color, null, null, true); // Start with the current source image
+ }
+
+ /**
+ * Draws the trail effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.lock();
+ targetBitmap.merge(whiteBitmap, rect, point, fade, fade, fade, 0); // Repeatedly fade out the image
+ targetBitmap.draw(sourceBitmap, null, null, BlendMode.DARKEN); // Blend the new source image with the old one
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the divide effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ whiteBitmap.dispose();
+ whiteBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/displace/AbstractDisplaceEffect.as b/webcam/com/neave/webcam/effects/displace/AbstractDisplaceEffect.as new file mode 100755 index 0000000..89458ac --- /dev/null +++ b/webcam/com/neave/webcam/effects/displace/AbstractDisplaceEffect.as @@ -0,0 +1,64 @@ +/**
+ * Neave Webcam // Abstract Displace Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import com.neave.webcam.effects.*;
+
+ internal class AbstractDisplaceEffect extends AbstractEffect
+ {
+ protected var displace:DisplacementMapFilter;
+
+ /**
+ * An abstract displacement effect class, not to be instantiated
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param name The proper name of the effect
+ */
+ public function AbstractDisplaceEffect(source:IBitmapDrawable, targetBitmap:BitmapData, name:String = "")
+ {
+ super(source, targetBitmap, name);
+
+ createAbstractDisplace();
+ }
+
+ /**
+ * Sets up the displacement effect
+ */
+ private function createAbstractDisplace():void
+ {
+ // Create a displacement map filter with grey bitmap data, using red to distort horizontally, green to distort vertically
+ displace = new DisplacementMapFilter(new BitmapData(rect.width, rect.height, false, 0xFF808080), point, BitmapDataChannel.RED, BitmapDataChannel.GREEN, 0, 0, DisplacementMapFilterMode.CLAMP);
+ }
+
+ /**
+ * Draws the displacement effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.applyFilter(sourceBitmap, rect, point, displace);
+ }
+
+ /**
+ * Removes the displacement effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ displace.mapBitmap.dispose();
+ displace = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/displace/BulgeEffect.as b/webcam/com/neave/webcam/effects/displace/BulgeEffect.as new file mode 100755 index 0000000..d2c1ac2 --- /dev/null +++ b/webcam/com/neave/webcam/effects/displace/BulgeEffect.as @@ -0,0 +1,74 @@ +/**
+ * Neave Webcam // Bulge Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class BulgeEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a bulge effect that pushes the centre of the image outwards
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function BulgeEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Bulge");
+
+ createBulge();
+ }
+
+ /**
+ * Sets up the bulge effect
+ */
+ private function createBulge():void
+ {
+ // The size of the bulge, one quarter the size of the source image
+ var w:int = rect.width;
+ var h:int = rect.height;
+ var size:int = Math.round((w + h) / 4);
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size, size);
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ cover.graphics.beginGradientFill(GradientType.RADIAL, [0x808080, 0x808080], [0, 1], [0x00, 0xFF], m);
+ cover.graphics.drawRect(0, 0, size, size);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0xFF0000, 0x000000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, size, size);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.rotate(Math.PI / 2);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x00FF00, 0x000000], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, size, size);
+
+ // Draw all the gradients into one displacement map bitmap
+ var mapMatrix:Matrix = new Matrix();
+ mapMatrix.translate(w / 2 - size / 2, h / 2 - size / 2);
+ displace.mapBitmap.draw(red, mapMatrix);
+ displace.mapBitmap.draw(green, mapMatrix, null, BlendMode.ADD);
+ displace.mapBitmap.draw(cover, mapMatrix);
+
+ // Set the size of the displacement
+ displace.scaleX = displace.scaleY = size;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/displace/DentEffect.as b/webcam/com/neave/webcam/effects/displace/DentEffect.as new file mode 100755 index 0000000..c701146 --- /dev/null +++ b/webcam/com/neave/webcam/effects/displace/DentEffect.as @@ -0,0 +1,75 @@ +/**
+ * Neave Webcam // Dent Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class DentEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a dent effect that pinches the centre of the image inwards
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function DentEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Dent");
+
+ createDent();
+ }
+
+ /**
+ * Sets up the dent effect
+ */
+ private function createDent():void
+ {
+ // The size of the dent, one quarter the size of the source image
+ var w:int = rect.width;
+ var h:int = rect.height;
+ var size:int = Math.round((w + h) / 4);
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size, size);
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ cover.graphics.beginGradientFill(GradientType.RADIAL, [0x808080, 0x808080], [0, 1], [0x00, 0xFF], m);
+ cover.graphics.drawRect(0, 0, size, size);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0x000000, 0xFF0000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, size, size);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.rotate(Math.PI / 2);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x000000, 0x00FF00], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, size, size);
+
+ // Draw all the gradients into one displacement map bitmap
+ var mapMatrix:Matrix = new Matrix();
+ mapMatrix.translate(w / 2 - size / 2, h / 2 - size / 2);
+ displace.mapBitmap.draw(red, mapMatrix);
+ displace.mapBitmap.draw(green, mapMatrix, null, BlendMode.ADD);
+ displace.mapBitmap.draw(cover, mapMatrix);
+
+ // Double up the grey cover for a greater dent size
+ displace.mapBitmap.draw(cover, mapMatrix);
+ displace.scaleX = displace.scaleY = size * 2;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/displace/FishbowlEffect.as b/webcam/com/neave/webcam/effects/displace/FishbowlEffect.as new file mode 100755 index 0000000..08f5d08 --- /dev/null +++ b/webcam/com/neave/webcam/effects/displace/FishbowlEffect.as @@ -0,0 +1,72 @@ +/**
+ * Neave Webcam // Fishbowl Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class FishbowlEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a fishbowl effect like looking into a fishbowl, the opposite of the fisheye effect
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function FishbowlEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Fishbowl");
+
+ createFishbowl();
+ }
+
+ /**
+ * Sets up the fishbowl effect
+ */
+ private function createFishbowl():void
+ {
+ // The size of the fishbowl effect
+ var w:int = rect.width;
+ var h:int = rect.height;
+ var size:int = Math.round(Math.sqrt((w / 2) * (w / 2) + (h / 2) * (h / 2)) * 2);
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size, size, 0, w / 2 - size / 2, h / 2 - size / 2);
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ cover.graphics.beginGradientFill(GradientType.RADIAL, [0x808080, 0x808080], [1, 0], [0x00, 0xFF], m);
+ cover.graphics.drawRect(0, 0, w, h);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0xFF0000, 0x000000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, w, h);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.rotate(Math.PI / 2);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x00FF00, 0x000000], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, w, h);
+
+ // Draw all the gradients into one displacement map bitmap
+ displace.mapBitmap.draw(red);
+ displace.mapBitmap.draw(green, null, null, BlendMode.ADD);
+ displace.mapBitmap.draw(cover);
+
+ // Set the size of the displacement
+ displace.scaleX = displace.scaleY = size;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/displace/FisheyeEffect.as b/webcam/com/neave/webcam/effects/displace/FisheyeEffect.as new file mode 100755 index 0000000..1d4cf4a --- /dev/null +++ b/webcam/com/neave/webcam/effects/displace/FisheyeEffect.as @@ -0,0 +1,72 @@ +/**
+ * Neave Webcam // Fisheye Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class FisheyeEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a fisheye (wide-angle) lens effect
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function FisheyeEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Fisheye");
+
+ createFisheye();
+ }
+
+ /**
+ * Sets up the fisheye effect
+ */
+ private function createFisheye():void
+ {
+ // The size of the fisheye effect
+ var w:int = rect.width;
+ var h:int = rect.height;
+ var size:int = (w + h) / 2;
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size, size, 0, w / 2 - size / 2, h / 2 - size / 2);
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ cover.graphics.beginGradientFill(GradientType.RADIAL, [0x808080, 0x808080], [0, 1], [0x00, 0xFF], m, SpreadMethod.REFLECT);
+ cover.graphics.drawRect(0, 0, w, h);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0xFF0000, 0x000000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, w, h);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.rotate(Math.PI / 2);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x00FF00, 0x000000], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, w, h);
+
+ // Draw all the gradients into one displacement map bitmap
+ displace.mapBitmap.draw(red);
+ displace.mapBitmap.draw(green, null, null, BlendMode.ADD);
+ displace.mapBitmap.draw(cover);
+
+ // Set the size of the displacement
+ displace.scaleX = displace.scaleY = size;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/displace/FragmentEffect.as b/webcam/com/neave/webcam/effects/displace/FragmentEffect.as new file mode 100755 index 0000000..e058dd9 --- /dev/null +++ b/webcam/com/neave/webcam/effects/displace/FragmentEffect.as @@ -0,0 +1,101 @@ +/**
+ * Neave Webcam // Fragment Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class FragmentEffect extends AbstractEffect
+ {
+ private var fragmentsWide:int;
+ private var scale:Number;
+ private var total:int;
+ private var fragmentBitmap:BitmapData;
+ private var fragmentMatrix:Matrix;
+ private var fragmentRects:Array;
+ private var fragmentPoints:Array;
+
+ /**
+ * Creates a fragmentary effect where the image is divided into a grid of smaller zoomed areas
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param fragmentsWide The number of fragments in width to use
+ * @param scale The size of the zoom for each fragment
+ */
+ public function FragmentEffect(source:IBitmapDrawable, targetBitmap:BitmapData, fragmentsWide:int = 10, scale:Number = 0.5)
+ {
+ super(source, targetBitmap, "Fragment");
+ this.fragmentsWide = fragmentsWide < 1 ? 1 : fragmentsWide;
+ this.scale = scale;
+ if (scale > 2) this.scale = 2;
+ if (scale < 0.5) this.scale = 0.5;
+
+ createFragment();
+ }
+
+ /**
+ * Sets up the fragment effect
+ */
+ private function createFragment():void
+ {
+ // The fragment dimensions
+ var w:Number = rect.width / fragmentsWide;
+ var h:Number = rect.height / fragmentsWide;
+
+ // Set up the main fragment bitmap data and scaling properties
+ fragmentBitmap = new BitmapData(rect.width * scale, rect.height * scale, false, 0xFF000000);
+ fragmentMatrix = new Matrix();
+ fragmentMatrix.scale(1 / scale, 1 / scale);
+ fragmentRects = new Array();
+ fragmentPoints = new Array();
+
+ // Set up each fragment's area and position
+ for (var y:int = 0; y < fragmentsWide; y++)
+ {
+ for (var x:int = 0; x < fragmentsWide; x++)
+ {
+ fragmentRects.push(new Rectangle(x * w, y * h, w * scale, h * scale));
+ fragmentPoints.push(new Point(x * w * scale, y * h * scale));
+ }
+ }
+ total = fragmentsWide * fragmentsWide;
+ }
+
+ /**
+ * Draws the fragment effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through each fragment and draw the zoomed area
+ for (var i:int = total; i--; ) fragmentBitmap.copyPixels(sourceBitmap, fragmentRects[i], fragmentPoints[i]);
+
+ // Draw the fragment bitmap data into the target bitmap data but scaled to fit
+ targetBitmap.draw(fragmentBitmap, fragmentMatrix, null, null, null, true);
+ }
+
+ /**
+ * Removes the fragment effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ fragmentBitmap.dispose();
+ fragmentBitmap = null;
+ fragmentRects = null;
+ fragmentPoints = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/displace/SqueezeEffect.as b/webcam/com/neave/webcam/effects/displace/SqueezeEffect.as new file mode 100755 index 0000000..e702dc1 --- /dev/null +++ b/webcam/com/neave/webcam/effects/displace/SqueezeEffect.as @@ -0,0 +1,87 @@ +/**
+ * Neave Webcam // Squeeze Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class SqueezeEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a squeezing distortion effect where the middle is squeezed and the edges are stretched
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function SqueezeEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Squeeze");
+
+ createSqueeze();
+ }
+
+ /**
+ * Sets up the squeeze effect
+ */
+ private function createSqueeze():void
+ {
+ // The size of the squeeze effect
+ var w:int = rect.width;
+ var h:int = rect.height;
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ m.createGradientBox(w, w);
+ cover.graphics.beginGradientFill(GradientType.LINEAR, [0x808080, 0x808080], [1, 0], [0x00, 0xFF], m);
+ cover.graphics.drawRect(0, 0, w, w);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ m.createGradientBox(h, h, 0, (w - h) / 2, 0);
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0x000000, 0xFF0000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, w, w);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.createGradientBox(h, h, Math.PI / 2, (w - h) / 2, 0);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x000000, 0x00FF00], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, w, w);
+
+ // Draw red and green gradients into one displacement map bitmap
+ displace.mapBitmap.draw(red);
+ displace.mapBitmap.draw(green, null, null, BlendMode.ADD);
+
+ // Fade out the edges of the distorion linearly in each direction, up, down, left and right
+ m.identity();
+ m.scale(0.5, 1);
+ displace.mapBitmap.draw(cover, m);
+ m.rotate(Math.PI);
+ m.translate(w, h);
+ displace.mapBitmap.draw(cover, m);
+ m.identity();
+ m.scale(h / w / 2, 1);
+ m.rotate(Math.PI / 2);
+ m.translate(w, 0);
+ displace.mapBitmap.draw(cover, m);
+ m.rotate(Math.PI);
+ m.translate(w, h);
+ displace.mapBitmap.draw(cover, m);
+
+ // Set the size of the displacement
+ displace.scaleX = displace.scaleY = w;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/displace/WaterEffect.as b/webcam/com/neave/webcam/effects/displace/WaterEffect.as new file mode 100755 index 0000000..4f45d72 --- /dev/null +++ b/webcam/com/neave/webcam/effects/displace/WaterEffect.as @@ -0,0 +1,76 @@ +/**
+ * Neave Webcam // Water Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class WaterEffect extends AbstractDisplaceEffect
+ {
+ private var seed:int;
+ private var offsets:Array;
+ private var blue:ColorMatrixFilter;
+
+ /**
+ * Creates a water effect as if you were looking into a pool of waving water
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function WaterEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Water");
+
+ createWater();
+ }
+
+ /**
+ * Sets up the water effect
+ */
+ private function createWater():void
+ {
+ // Set up the displacement
+ displace.scaleX = rect.width * 0.25;
+ displace.scaleY = rect.height * 0.25;
+ seed = Math.floor(Math.random() * 256);
+ offsets = new Array(new Point(), new Point());
+
+ // Blue colour matrix
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, -10]); // Red
+ m = m.concat([0.3, 0.59, 0.11, 0, 30]); // Green
+ m = m.concat([0.3, 0.59, 0.11, 0, 70]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ blue = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the water effect
+ */
+ override public function draw():void
+ {
+ // Wave the water by moving the displacement map's offsets
+ offsets[0].x += rect.width * 0.06;
+ offsets[1].x += rect.height * 0.06;
+
+ // Generate perlin noise as a displacement map to make water waves
+ displace.mapBitmap.perlinNoise(rect.width * 0.5, rect.height * 0.5, 1, seed, false, true, BitmapDataChannel.RED | BitmapDataChannel.GREEN, false, offsets);
+
+ // Draw the displaced image and tint it blue
+ targetBitmap.lock();
+ super.draw();
+ targetBitmap.applyFilter(targetBitmap, rect, point, blue);
+ targetBitmap.unlock();
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/mirror/AbstractMirrorEffect.as b/webcam/com/neave/webcam/effects/mirror/AbstractMirrorEffect.as new file mode 100755 index 0000000..57008f7 --- /dev/null +++ b/webcam/com/neave/webcam/effects/mirror/AbstractMirrorEffect.as @@ -0,0 +1,68 @@ +/**
+ * Neave Webcam // Abstract Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ internal class AbstractMirrorEffect extends AbstractEffect
+ {
+ protected var mirrorBitmap:BitmapData;
+ protected var mirrorMatrix:Matrix;
+ protected var mirrorPoint:Point;
+
+ /**
+ * An abstract mirror effect class, not to be instantiated
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param name The proper name of the effect
+ */
+ public function AbstractMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData, name:String = "")
+ {
+ super(source, targetBitmap, name);
+
+ createAbstractMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createAbstractMirror():void
+ {
+ mirrorMatrix = new Matrix();
+ mirrorPoint = new Point();
+ }
+
+ /**
+ * Draws the mirror effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ mirrorBitmap.draw(sourceBitmap, mirrorMatrix);
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ targetBitmap.copyPixels(mirrorBitmap, rect, mirrorPoint);
+ }
+
+ /**
+ * Removes the mirror effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ mirrorBitmap.dispose();
+ mirrorBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/mirror/BottomMirrorEffect.as b/webcam/com/neave/webcam/effects/mirror/BottomMirrorEffect.as new file mode 100755 index 0000000..4bb7b07 --- /dev/null +++ b/webcam/com/neave/webcam/effects/mirror/BottomMirrorEffect.as @@ -0,0 +1,41 @@ +/**
+ * Neave Webcam // Bottom Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class BottomMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the bottom half of the image is reflected into the top half
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function BottomMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Bottom Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ mirrorMatrix.scale(1, -1);
+ mirrorMatrix.translate(0, rect.height);
+ mirrorBitmap = new BitmapData(rect.width, Math.round(rect.height / 2), false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/mirror/InverseMirrorEffect.as b/webcam/com/neave/webcam/effects/mirror/InverseMirrorEffect.as new file mode 100755 index 0000000..8f0da4c --- /dev/null +++ b/webcam/com/neave/webcam/effects/mirror/InverseMirrorEffect.as @@ -0,0 +1,41 @@ +/**
+ * Neave Webcam // Inverse Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class InverseMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the top half of the image is inversed
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function InverseMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Inverse Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ mirrorMatrix.scale(-1, 1);
+ mirrorMatrix.translate(rect.width, 0);
+ mirrorBitmap = new BitmapData(rect.width, Math.round(rect.height / 2), false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/mirror/LeftMirrorEffect.as b/webcam/com/neave/webcam/effects/mirror/LeftMirrorEffect.as new file mode 100755 index 0000000..31cc510 --- /dev/null +++ b/webcam/com/neave/webcam/effects/mirror/LeftMirrorEffect.as @@ -0,0 +1,41 @@ +/**
+ * Neave Webcam // Left Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class LeftMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the left side of the image is reflected into the right side (when using a flipped image)
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function LeftMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Left Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ mirrorMatrix.scale(-1, 1);
+ mirrorMatrix.translate(rect.width, 0);
+ mirrorBitmap = new BitmapData(Math.round(rect.width / 2), rect.height, false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/mirror/QuadMirrorEffect.as b/webcam/com/neave/webcam/effects/mirror/QuadMirrorEffect.as new file mode 100755 index 0000000..d4e84a4 --- /dev/null +++ b/webcam/com/neave/webcam/effects/mirror/QuadMirrorEffect.as @@ -0,0 +1,97 @@ +/**
+ * Neave Webcam // Quad Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class QuadMirrorEffect extends AbstractEffect
+ {
+ private var quadBitmap:BitmapData;
+ private var halfBitmap:BitmapData;
+ private var quadMatrix:Matrix;
+ private var rightMatrix:Matrix;
+ private var topMatrix:Matrix;
+ private var bottomMatrix:Matrix;
+
+ /**
+ * Creates a mirror effect where the source image is reflected vertically and horizontally
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function QuadMirrorEffect(source:IBitmapDrawable, targetBitmapData:BitmapData)
+ {
+ super(source, targetBitmapData, "Quad Mirror");
+
+ createQuadMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createQuadMirror():void
+ {
+ // Mirror dimensions
+ var midW:int = Math.round(rect.width / 2);
+ var midH:int = Math.round(rect.height / 2);
+
+ // Reflected bitmap data
+ quadBitmap = new BitmapData(midW, midH, false, 0xFF000000);
+ halfBitmap = new BitmapData(rect.width, midH, false, 0xFF000000);
+
+ // Half size matrix
+ quadMatrix = new Matrix();
+ quadMatrix.scale(0.5, 0.5);
+
+ // Right side matrix
+ rightMatrix = new Matrix();
+ rightMatrix.scale(-1, 1);
+ rightMatrix.translate(rect.width, 0);
+
+ // Top half matrix
+ topMatrix = new Matrix();
+ topMatrix.scale(1, -1);
+ topMatrix.translate(0, midH);
+
+ // Bottom half matrix
+ bottomMatrix = new Matrix();
+ bottomMatrix.translate(0, midH);
+ }
+
+ /**
+ * Draws the quad mirror effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ quadBitmap.draw(sourceBitmap, quadMatrix); // Draw quarter image
+ halfBitmap.draw(quadBitmap); // Draw quarter into left
+ halfBitmap.draw(quadBitmap, rightMatrix); // Draw quarter into right
+ targetBitmap.draw(halfBitmap, bottomMatrix); // Draw half into bottom
+ targetBitmap.draw(halfBitmap, topMatrix); // Draw half into top
+ }
+
+ /**
+ * Removes the quad mirror effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ quadBitmap.dispose();
+ quadBitmap = null;
+ halfBitmap.dispose();
+ halfBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/mirror/RightMirrorEffect.as b/webcam/com/neave/webcam/effects/mirror/RightMirrorEffect.as new file mode 100755 index 0000000..d469226 --- /dev/null +++ b/webcam/com/neave/webcam/effects/mirror/RightMirrorEffect.as @@ -0,0 +1,44 @@ +/**
+ * Neave Webcam // Right Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class RightMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the right side of the image is reflected into the left side (when using a flipped image)
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function RightMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Right Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ var midW:int = Math.round(rect.width / 2);
+
+ mirrorMatrix.scale(-1, 1);
+ mirrorMatrix.translate(midW, 0);
+ mirrorPoint.x = midW;
+ mirrorBitmap = new BitmapData(midW, rect.height, false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/mirror/TopMirrorEffect.as b/webcam/com/neave/webcam/effects/mirror/TopMirrorEffect.as new file mode 100755 index 0000000..af69612 --- /dev/null +++ b/webcam/com/neave/webcam/effects/mirror/TopMirrorEffect.as @@ -0,0 +1,44 @@ +/**
+ * Neave Webcam // Top Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class TopMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the top half of the image is reflected into the bottom half
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function TopMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Top Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ var midH:int = Math.round(rect.height / 2);
+
+ mirrorMatrix.scale(1, -1);
+ mirrorMatrix.translate(0, midH);
+ mirrorPoint.y = midH;
+ mirrorBitmap = new BitmapData(rect.width, midH, false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/mirror/UpsideDownEffect.as b/webcam/com/neave/webcam/effects/mirror/UpsideDownEffect.as new file mode 100755 index 0000000..71e08d8 --- /dev/null +++ b/webcam/com/neave/webcam/effects/mirror/UpsideDownEffect.as @@ -0,0 +1,54 @@ +/**
+ * Neave Webcam // Upside-Down Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class UpsideDownEffect extends AbstractEffect
+ {
+ private var flipMatrix:Matrix;
+
+ /**
+ * Creates a mirror effect where the source image is flipped vertically
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function UpsideDownEffect(source:IBitmapDrawable, targetBitmapData:BitmapData)
+ {
+ super(source, targetBitmapData, "Upside-Down");
+
+ createUpsideDown();
+ }
+
+ /**
+ * Sets up the upside-down effect
+ */
+ private function createUpsideDown():void
+ {
+ flipMatrix = new Matrix();
+ flipMatrix.scale(1, -1);
+ flipMatrix.translate(0, rect.height);
+ }
+
+ /**
+ * Draws the upside-down effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.draw(sourceBitmap, flipMatrix);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/motion/AbstractMotionEffect.as b/webcam/com/neave/webcam/effects/motion/AbstractMotionEffect.as new file mode 100755 index 0000000..3301a8a --- /dev/null +++ b/webcam/com/neave/webcam/effects/motion/AbstractMotionEffect.as @@ -0,0 +1,138 @@ +/**
+ * Neave Webcam // Abstract Motion Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ internal class AbstractMotionEffect extends AbstractEffect
+ {
+ private var motionScale:int;
+ private var motionFrames:int;
+ private var contrast:ColorTransform;
+ private var frames:Array;
+ private var frameBitmap:BitmapData;
+ protected var monochrome:ColorMatrixFilter;
+ protected var motionBitmap:BitmapData;
+ protected var motionRect:Rectangle;
+ protected var motionMatrix:Matrix;
+
+ /**
+ * An abstract motion detection effect class, not to be instantiated
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param name The proper name of the effect
+ * @param motionScale The scale of the motion bitmap data to use for detection
+ * @param motionFrames The number of frames to capture for the motion bitmap data
+ */
+ public function AbstractMotionEffect(source:IBitmapDrawable, targetBitmap:BitmapData, name:String = "", motionScale:int = 1, motionFrames:int = 4)
+ {
+ super(source, targetBitmap, name);
+ this.motionScale = motionScale < 1 ? 1 : motionScale;
+ this.motionFrames = motionFrames < 1 ? 1 : motionFrames;
+
+ createAbstractMotion();
+ }
+
+ /**
+ * Sets up the motion effect
+ */
+ private function createAbstractMotion():void
+ {
+ // Increase contrast
+ contrast = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Motion bitmap dimensions
+ var w:int = Math.round(rect.width / motionScale);
+ var h:int = Math.round(rect.height / motionScale);
+
+ // Main motion bitmap data
+ motionBitmap = new BitmapData(w, h, false, 0xFF000000);
+ motionRect = motionBitmap.rect;
+ motionMatrix = new Matrix();
+ motionMatrix.scale(1 / motionScale, 1 / motionScale);
+
+ // The previous frame to use when comparing with the current image
+ frameBitmap = motionBitmap.clone();
+ frameBitmap.draw(source, motionMatrix, contrast);
+
+ // Create the delayed motion frames
+ frames = new Array();
+ for (var i:int = motionFrames; i--; ) frames.push(new BitmapData(w, h, false, 0xFF000000));
+
+ // Monochrome colour matrix
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Red
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Green
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ monochrome = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the motion effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Clear old motion bitmap
+ motionBitmap.fillRect(motionRect, 0xFF000000);
+
+ // Do motion detection
+ for (var i:int = motionFrames; i--; )
+ {
+ var b:BitmapData = frames[i];
+ if (i == 0)
+ {
+ // Detect motion by taking the difference between this source image to the previous source image
+ b.copyPixels(frameBitmap, motionRect, point); // Get the old image
+ frameBitmap.draw(sourceBitmap, motionMatrix, contrast); // Draw the new image
+ frameBitmap.applyFilter(frameBitmap, motionRect, point, monochrome); // Convert the new image to greyscale
+ b.draw(frameBitmap, null, null, BlendMode.DIFFERENCE); // Draw the difference
+ }
+ else b.copyPixels(frames[i - 1], motionRect, point); // Move the motion frames along the array
+
+ // Add all the motion frames into a single bitmap
+ motionBitmap.draw(b, null, null, BlendMode.ADD);
+ }
+
+ // Separate the motion bitmap data into only black and white pixels
+ motionBitmap.threshold(motionBitmap, motionRect, point, ">", 0xFF808080, 0xFFFFFFFF);
+ motionBitmap.threshold(motionBitmap, motionRect, point, "<=", 0xFF808080, 0xFF000000);
+ }
+
+ /**
+ * Removes the motion effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the motion frames
+ for (var i:int = motionFrames; i--; )
+ {
+ frames[i].dispose();
+ frames[i] = null;
+ }
+ frames = null;
+
+ frameBitmap.dispose();
+ frameBitmap = null;
+ motionBitmap.dispose();
+ motionBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/motion/FireEffect.as b/webcam/com/neave/webcam/effects/motion/FireEffect.as new file mode 100755 index 0000000..33dcfe2 --- /dev/null +++ b/webcam/com/neave/webcam/effects/motion/FireEffect.as @@ -0,0 +1,129 @@ +/**
+ * Neave Webcam // Fire Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class FireEffect extends AbstractMotionEffect
+ {
+ private const MOTION_SCALE:int = 2;
+
+ private var fireSourceBitmap:BitmapData;
+ private var fireBitmap:BitmapData;
+ private var darkenBitmap:BitmapData;
+ private var edge:ConvolutionFilter;
+ private var fireColor:ColorMatrixFilter;
+ private var displace:DisplacementMapFilter;
+ private var blur:BlurFilter;
+ private var targetMatrix:Matrix;
+
+ /**
+ * Creates a fire effect which animates along edges and as motion is detected
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function FireEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Fire", MOTION_SCALE, 5);
+
+ createFire();
+ }
+
+ /**
+ * Sets up the fire effect
+ */
+ private function createFire():void
+ {
+ // Set up fire bitmap data and scaling
+ fireSourceBitmap = motionBitmap.clone();
+ fireBitmap = motionBitmap.clone();
+ targetMatrix = new Matrix();
+ targetMatrix.scale(MOTION_SCALE, MOTION_SCALE);
+
+ // Edge detection convolution array
+ var m:Array =
+ [
+ 0, 0, 0,
+ 16, 16, 16,
+ -16, -16, -16
+ ];
+ edge = new ConvolutionFilter(3, 3, m, 9);
+
+ // Fire colour matrix
+ m = new Array();
+ m = m.concat([0.8, 0.05, 0, 0, 0]); // Red
+ m = m.concat([0, 0.65, 0, 0, 0]); // Green
+ m = m.concat([0, 0, 0.5, 0, 0]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ fireColor = new ColorMatrixFilter(m);
+
+ // Fire displacement map
+ displace = new DisplacementMapFilter(new BitmapData(rect.width, rect.height, false, 0xFF808080), point, BitmapDataChannel.RED, BitmapDataChannel.GREEN, 7, -35, DisplacementMapFilterMode.CLAMP);
+
+ // Fire blurring
+ blur = new BlurFilter(8, 8, 1);
+
+ // Darken the fire
+ darkenBitmap = new BitmapData(rect.width, rect.height, false, 0xFFFF8000);
+ }
+
+ /**
+ * Draws the fire effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Get the source image's edges
+ fireSourceBitmap.draw(sourceBitmap, motionMatrix);
+ fireBitmap.applyFilter(fireSourceBitmap, motionRect, point, edge);
+ fireBitmap.applyFilter(fireBitmap, motionRect, point, monochrome);
+
+ // Add motion bitmap to edge bitmap and turn pixels into orange and black only
+ fireBitmap.draw(motionBitmap, null, null, BlendMode.ADD);
+ fireBitmap.threshold(fireBitmap, motionRect, point, ">", 0xFF808080, 0xFFFF8000);
+ fireBitmap.threshold(fireBitmap, motionRect, point, "<=", 0xFF808080, 0xFF000000);
+
+ // Blur to make motion bitmap look more like fire
+ fireBitmap.applyFilter(fireBitmap, motionRect, point, blur);
+
+ // Displace the image with perlin noise to animate the fire
+ displace.mapBitmap.perlinNoise(14, 10, 1, Math.floor(Math.random() * 256), false, true, BitmapDataChannel.RED | BitmapDataChannel.GREEN, false);
+ displace.mapBitmap.draw(darkenBitmap, null, null, BlendMode.DARKEN);
+ fireBitmap.applyFilter(fireBitmap, motionRect, point, displace);
+ fireBitmap.applyFilter(fireBitmap, motionRect, point, fireColor);
+
+ // Draw the fire bitmap on top of the current source image
+ targetBitmap.lock();
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ targetBitmap.draw(fireBitmap, targetMatrix, null, BlendMode.ADD);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the fire effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ fireSourceBitmap.dispose();
+ fireSourceBitmap = null;
+ fireBitmap.dispose();
+ fireBitmap = null;
+ darkenBitmap.dispose();
+ darkenBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/motion/SnowEffect.as b/webcam/com/neave/webcam/effects/motion/SnowEffect.as new file mode 100755 index 0000000..30468d9 --- /dev/null +++ b/webcam/com/neave/webcam/effects/motion/SnowEffect.as @@ -0,0 +1,154 @@ +/**
+ * Neave Webcam // Snow Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.events.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import flash.utils.*;
+ import com.neave.webcam.effects.*;
+
+ public class SnowEffect extends AbstractEffect
+ {
+ private const SNOWFLAKE_DELAY:int = 20;
+ private const MELT_SPEED:Number = 0.0025;
+
+ private var totalFlakes:int;
+ private var snowSourceBitmap:BitmapData;
+ private var edgeBitmap:BitmapData;
+ private var edge:ConvolutionFilter;
+ private var blur:BlurFilter;
+ private var snowflakes:Sprite;
+ private var snowTimer:Timer;
+ private var snowMatrix:Matrix;
+ private var contrast:ColorTransform;
+
+ /**
+ * Creates a snow effect where falling snowflakes settle and build up along edges
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param totalFlakes The total number of snowflakes to use
+ */
+ public function SnowEffect(source:IBitmapDrawable, targetBitmap:BitmapData, totalFlakes:int = 200)
+ {
+ super(source, targetBitmap, "Snow");
+ this.totalFlakes = totalFlakes < 1 ? 1 : totalFlakes;
+
+ createSnow();
+ }
+
+ /**
+ * Sets up the snow effect
+ */
+ private function createSnow():void
+ {
+ // Increase contrast to better detect edges
+ //contrast = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Create bitmaps to hold edge detection
+ snowSourceBitmap = new BitmapData(Math.round(rect.width / 2), Math.round(rect.height / 2), false, 0xFF000000);
+ edgeBitmap = snowSourceBitmap.clone();
+ snowMatrix = new Matrix();
+ snowMatrix.scale(0.5, 0.5);
+
+ // Add a new snowflake to the snowflakes sprite every so often
+ snowflakes = new Sprite();
+ snowTimer = new Timer(SNOWFLAKE_DELAY);
+ snowTimer.addEventListener(TimerEvent.TIMER, makeNewSnowflake);
+ snowTimer.start();
+
+ // Edge detection convolution array
+ var m:Array =
+ [
+ 0, 50, 0,
+ 0, -60, 0,
+ 0, 10, 0
+ ];
+ edge = new ConvolutionFilter(3, 3, m, 5);
+ }
+
+ /**
+ * Creates a new snowflake inside the snowflakes sprite
+ */
+ private function makeNewSnowflake(e:TimerEvent = null):void
+ {
+ // Only add another random snowflake if the maximum amount has not been reached
+ if (snowflakes.numChildren < totalFlakes) snowflakes.addChild(new Snowflake(Math.random() * rect.width, -4, Math.random() * 2 + 1, Math.random() * 2 - 1));
+ }
+
+ /**
+ * Draws the snow effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through each snowflake
+ for (var i:int = snowflakes.numChildren; i--; )
+ {
+ var flake:Snowflake = snowflakes.getChildAt(i) as Snowflake;
+
+ // Only move the snowflake if it is not hitting an edge
+ if (edgeBitmap.getPixel(Math.round(flake.x / 2), Math.round(flake.y / 2)) == 0x000000)
+ {
+ // Animate the snowflake
+ flake.fall();
+ flake.alpha += 0.1;
+ if (flake.alpha > 1) flake.alpha = 1;
+
+ // Wrap the snowflake to within the bounds of the image
+ if (flake.x > rect.width + flake.width) flake.x -= rect.width + flake.width;
+ if (flake.x < -flake.width) flake.x += rect.width + flake.width;
+
+ // Remove this snowflake if it has fallen off the bottom of the image
+ if (flake.y > rect.height + flake.height) snowflakes.removeChildAt(i);
+ }
+ else
+ {
+ // Melt this snowflake by fading out it
+ if (flake.alpha > 0.1) flake.alpha -= MELT_SPEED;
+ else snowflakes.removeChildAt(i);
+ }
+ }
+
+ // Find the edges for the snow to settle on
+ snowSourceBitmap.draw(sourceBitmap, snowMatrix, contrast);
+ edgeBitmap.applyFilter(snowSourceBitmap, edgeBitmap.rect, point, edge);
+ edgeBitmap.threshold(edgeBitmap, edgeBitmap.rect, point, "<", 0xFF808080, 0xFF000000);
+
+ // Draw the snow over the current source image
+ targetBitmap.lock();
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ targetBitmap.draw(snowflakes);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the snow effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Stop making new snowflakes
+ snowTimer.removeEventListener(TimerEvent.TIMER, makeNewSnowflake);
+
+ // Remove bitmap data
+ snowSourceBitmap.dispose();
+ snowSourceBitmap = null;
+ edgeBitmap.dispose();
+ edgeBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/motion/Snowflake.as b/webcam/com/neave/webcam/effects/motion/Snowflake.as new file mode 100755 index 0000000..fc943f5 --- /dev/null +++ b/webcam/com/neave/webcam/effects/motion/Snowflake.as @@ -0,0 +1,66 @@ +/**
+ * Neave Webcam // Snowflake
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.geom.*;
+
+ final internal class Snowflake extends Shape
+ {
+ private const SIDEWAYS_DAMPEN:Number = 0.995;
+
+ private var size:Number;
+ private var vx:Number;
+
+ /**
+ * Draws a snowflake shape to be used with the snow effect
+ *
+ * @param x The position of the snowflake on the x-axis
+ * @param y The position of the snowflake on the y-axis
+ * @param size The size of the snowflake
+ * @param vx The sideways velocity of the snowflake
+ */
+ public function Snowflake(x:Number = 0, y:Number = 0, size:Number = 1, vx:Number = 0)
+ {
+ this.x = x;
+ this.y = y;
+ this.size = size;
+ this.vx = vx;
+
+ createSnowflake();
+ }
+
+ /**
+ * Sets up the snowflake shape, a white oval gradient
+ */
+ private function createSnowflake():void
+ {
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size * 2, size * 2);
+ m.translate(-size, -size);
+ graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0xFFFFFF], [1, 0], [0x66, 0xFF], m);
+ graphics.drawCircle(0, 0, size);
+ width *= 1.5;
+ cacheAsBitmap = true;
+ }
+
+ /**
+ * Animates the snowflake downwards
+ */
+ internal function fall():void
+ {
+ vx *= SIDEWAYS_DAMPEN;
+ x += vx;
+ y += size;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/motion/SteamEffect.as b/webcam/com/neave/webcam/effects/motion/SteamEffect.as new file mode 100755 index 0000000..0b55ca2 --- /dev/null +++ b/webcam/com/neave/webcam/effects/motion/SteamEffect.as @@ -0,0 +1,73 @@ +/**
+ * Neave Webcam // Steamy Window Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+
+ public class SteamEffect extends AbstractMotionEffect
+ {
+ private var steamBitmap:BitmapData;
+ private var blackBitmap:BitmapData;
+ private var wipedBitmap:BitmapData;
+
+ /**
+ * Creates a steamy window effect where detected motion wipes away areas of the steamed-up image
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function SteamEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Steamy Window");
+
+ createSteam();
+ }
+
+ /**
+ * Sets up the steam effect
+ */
+ private function createSteam():void
+ {
+ steamBitmap = new BitmapData(rect.width, rect.height, false, 0xFF808080);
+ blackBitmap = new BitmapData(rect.width, rect.height, false, 0xFF000000);
+ wipedBitmap = blackBitmap.clone();
+ }
+
+ /**
+ * Draws the steam effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ wipedBitmap.draw(motionBitmap, null, null, BlendMode.ADD); // Build up a wiped area by repeatedly adding the motion bitmap
+ wipedBitmap.merge(blackBitmap, rect, point, 2, 2, 2, 0); // Gradually fade away the wiped areas
+ steamBitmap.fillRect(rect, 0xFF808080); // Create some steam
+ steamBitmap.draw(wipedBitmap, null, null, BlendMode.SUBTRACT); // Remove the wiped areas from the steam
+ sourceBitmap.merge(steamBitmap, rect, point, 0x80, 0x80, 0x80, 0); // Merge the steam with the source image
+ targetBitmap.copyPixels(sourceBitmap, rect, point); // Draw into the target bitmap
+ }
+
+ /**
+ * Removes the steam effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ steamBitmap.dispose();
+ steamBitmap = null;
+ blackBitmap.dispose();
+ blackBitmap = null;
+ wipedBitmap.dispose();
+ wipedBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/motion/SwarmEffect.as b/webcam/com/neave/webcam/effects/motion/SwarmEffect.as new file mode 100755 index 0000000..f22a6bd --- /dev/null +++ b/webcam/com/neave/webcam/effects/motion/SwarmEffect.as @@ -0,0 +1,106 @@ +/**
+ * Neave Webcam // Swarm Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.geom.*;
+
+ public class SwarmEffect extends AbstractMotionEffect
+ {
+ private const MOTION_SCALE:int = 4;
+
+ private var flies:int;
+ private var swarm:Sprite;
+
+ /**
+ * Creates a swarming flies effect where the flies are attracted to detected motion
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param flies The number of flies to use in the swarm
+ */
+ public function SwarmEffect(source:IBitmapDrawable, targetBitmap:BitmapData, flies:int = 150)
+ {
+ super(source, targetBitmap, "Swarm", MOTION_SCALE);
+ this.flies = flies < 1 ? 1 : flies;
+
+ createSwarm();
+ }
+
+ /**
+ * Sets up the swarm effect
+ */
+ private function createSwarm():void
+ {
+ // Draw the flies into the swarm sprite in random positions
+ swarm = new Sprite();
+ for (var i:int = flies; i--; ) swarm.addChild(new SwarmFly(Math.random() * rect.width, Math.random() * rect.height, (i / flies) * 0.75 + 0.75));
+ }
+
+ /**
+ * Draws the swarm effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through each pixel in the motion bitmap data
+ var flyX:int = -1;
+ var flyY:int = -1;
+ for (var y:int = motionBitmap.height; y--; )
+ {
+ for (var x:int = motionBitmap.width; x--; )
+ {
+ // If this pixel has motion set this as a point for the flies to move to
+ if (motionBitmap.getPixel(x, y) == 0xFFFFFF)
+ {
+ flyX = x * MOTION_SCALE;
+ flyY = y * MOTION_SCALE;
+ break;
+ }
+ }
+ }
+
+ // Loop through each fly in the swarm
+ for (var i:int = flies; i--; )
+ {
+ // Fly the fly towards the motion point
+ var fly:SwarmFly = swarm.getChildAt(i) as SwarmFly;
+ fly.flyTo(flyX, flyY);
+
+ // Limit the fly to within bounds of the source image
+ if (fly.x < 0) fly.x = 0;
+ if (fly.y < 0) fly.y = 0;
+ if (fly.x > rect.width) fly.x = rect.width;
+ if (fly.y > rect.height) fly.y = rect.height;
+ }
+
+ // Draw the swarm over the source image
+ targetBitmap.lock();
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ targetBitmap.draw(swarm);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the swarm effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the flies from the swarm sprite
+ for (var i:int = flies; i--; ) swarm.removeChildAt(i);
+ swarm = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/motion/SwarmFly.as b/webcam/com/neave/webcam/effects/motion/SwarmFly.as new file mode 100755 index 0000000..a7cfe62 --- /dev/null +++ b/webcam/com/neave/webcam/effects/motion/SwarmFly.as @@ -0,0 +1,122 @@ +/**
+ * Neave Webcam // Swarm Fly
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.filters.*;
+
+ final internal class SwarmFly extends Shape
+ {
+ private const MAX_BOREDOM:int = 10;
+ private const BOREDOM_TIME:int = 20;
+ private const MAX_DIST:int = 8000;
+ private const BORED_DIST:int = 30;
+
+ private var x0:Number;
+ private var y0:Number;
+ private var size:Number;
+ private var speed:Number;
+ private var boredom:int;
+ private var wobbleAngle:Number;
+ private var wobbleDist:Number;
+ private var wobbleStep:Number;
+
+ /**
+ * Creates a fly graphic to be used with the swarm effect
+ *
+ * @param x The starting position of the fly on the x-axis
+ * @param y The starting position of the fly on the y-axis
+ */
+ public function SwarmFly(x:Number = 0, y:Number = 0, size:Number = 1)
+ {
+ this.x = x0 = x;
+ this.y = y0 = y;
+ this.size = size;
+
+ createFly();
+ }
+
+ /**
+ * Sets up the fly and its initial properties
+ */
+ private function createFly():void
+ {
+ // This fly's movement speed and initial boredom threshold
+ speed = Math.random() * 20 + 10;
+ boredom = Math.floor(Math.random() * (MAX_BOREDOM + BOREDOM_TIME));
+
+ // This fly's wobbling amount as it flies
+ wobbleAngle = Math.random() * Math.PI;
+ wobbleDist = Math.random() * 2.5 + 0.5;
+ wobbleStep = evenRandom() * 2;
+
+ // Draw the fly shape, a black circle with a black glow
+ graphics.beginFill(0x000000);
+ graphics.drawCircle(0, 0, size);
+ filters = [ new GlowFilter(0x000000, 1, 6, 6, 2, 2, false, false) ];
+ cacheAsBitmap = true;
+ }
+
+ /**
+ * Generates a random number between -0.5 and 0.5
+ */
+ private function evenRandom():Number
+ {
+ return Math.random() - 0.5;
+ }
+
+ /**
+ * Moves the fly towards the specified position
+ *
+ * @param x The position to move to on the x-axis
+ * @param y The position to move to on the y-axis
+ */
+ internal function flyTo(x:int, y:int):void
+ {
+ var dx:int = this.x - x;
+ var dy:int = this.y - y;
+ if (boredom > MAX_BOREDOM || dx * dx + dy * dy > MAX_DIST)
+ {
+ // Fly around if the fly is too bored or too far away
+ this.x += (x0 - this.x) / speed;
+ this.y += (y0 - this.y) / speed;
+
+ // Flying around reduces boredom
+ if (boredom > 0) boredom--;
+
+ // Not bored any more, reset boredom threshold
+ if (boredom == MAX_BOREDOM) boredom = 0;
+ }
+ else if (x >=0 || y >= 0)
+ {
+ // Fly isn't bored yet so moves towards the motion
+ this.x += (x - this.x) / speed / 2;
+ this.y += (y - this.y) / speed / 2;
+
+ // Boredom increases until the fly is totally bored and flies off
+ if (boredom < MAX_BOREDOM) boredom++;
+ else
+ {
+ // Bored now, so fly away somewhere for a time
+ x0 = x + evenRandom() * BORED_DIST;
+ y0 = y + evenRandom() * BORED_DIST;
+ boredom = MAX_BOREDOM + Math.ceil(evenRandom() * BOREDOM_TIME);
+ }
+ }
+
+ // Wobble the fly's movement
+ wobbleAngle += wobbleStep;
+ this.x += Math.sin(wobbleAngle) * wobbleDist;
+ this.y += Math.cos(wobbleAngle / 3) * wobbleDist;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/pixel/ASCIIEffect.as b/webcam/com/neave/webcam/effects/pixel/ASCIIEffect.as new file mode 100755 index 0000000..cd8e8d8 --- /dev/null +++ b/webcam/com/neave/webcam/effects/pixel/ASCIIEffect.as @@ -0,0 +1,225 @@ +/**
+ * Neave Webcam // ASCII Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import flash.system.*;
+ import flash.text.*;
+ import com.neave.webcam.effects.*;
+
+ public class ASCIIEffect extends AbstractEffect
+ {
+ private const FONT_NAME:String = "_typewriter";
+ private const FONT_SIZE:int = 10;
+ private const FONT_COLOR:int = 0x33FF33;
+ private const FONT_SPACING:int = 2;
+ private const FONT_WIN_LEADING:int = -8;
+ private const FONT_MAC_LEADING:int = -6;
+ private const CHARS_WIDE:int = 39;
+ private const MIN_ASCII_CHAR:uint = 32;
+ private const MAX_ASCII_CHAR:uint = 126;
+
+ private var flipChars:Boolean;
+ private var smallBitmap:BitmapData;
+ private var smallMatrix:Matrix;
+ private var textBitmap:BitmapData;
+ private var textfield:TextField;
+ private var textMatrix:Matrix;
+ private var flipMatrix:Matrix;
+ private var charsX:int;
+ private var charsY:int;
+ private var total:int;
+ private var textFormat:TextFormat;
+ private var chars:Array;
+ private var blur:BlurFilter;
+
+ /**
+ * Creates a text-based effect where each pixel is drawn as a letter from the ASCII character table
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param flipChars Flips the ASCII characters horizontally, useful if using a mirrored webcam as the source object
+ */
+ public function ASCIIEffect(source:IBitmapDrawable, targetBitmap:BitmapData, flipChars:Boolean = true)
+ {
+ super(source, targetBitmap, "ASCII");
+ this.flipChars = flipChars;
+
+ createASCII();
+ }
+
+ /**
+ * Sets up the ASCII effect
+ */
+ private function createASCII():void
+ {
+ // Increase contrast
+ color = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Create the main textfield
+ var fmt:TextFormat = new TextFormat(FONT_NAME, FONT_SIZE, FONT_COLOR);
+ fmt.letterSpacing = FONT_SPACING;
+ fmt.leading = Capabilities.version.substr(0, 3) == "MAC" ? FONT_MAC_LEADING : FONT_WIN_LEADING;
+ textfield = new TextField();
+ textfield.defaultTextFormat = fmt;
+ textfield.autoSize = TextFieldAutoSize.LEFT;
+
+ // Get the ASCII characters in order of brightness
+ chars = getOrderedChars();
+ total = chars.length - 1;
+
+ // Create a bitmap to hold the textfield
+ textBitmap = targetBitmap.clone();
+ textMatrix = new Matrix();
+ textMatrix.translate(3, 0);
+
+ // Create a smaller, lower resolution bitmap to sample pixels from
+ smallBitmap = new BitmapData(CHARS_WIDE, Math.round(CHARS_WIDE * rect.height / rect.width), false, 0xFF000000);
+ charsX = smallBitmap.width;
+ charsY = smallBitmap.height;
+ smallMatrix = new Matrix();
+ smallMatrix.scale(charsX / rect.width, charsY / rect.height);
+
+ // If flip flag is true, reverse the bitmaps horizontally
+ flipMatrix = new Matrix();
+ flipMatrix.scale(rect.width / 320, rect.height / 240);
+ if (flipChars)
+ {
+ flipMatrix.scale(-1, 1);
+ flipMatrix.translate(rect.width, 0);
+ smallMatrix.scale(-1, 1);
+ smallMatrix.translate(charsX, 0);
+ }
+
+ // Use a blur filter to add a slight glow behind the characters
+ blur = new BlurFilter(4, 4, 1);
+ }
+
+ /**
+ * Generates an array of ASCII characters in order of pixel brightness
+ *
+ * @return An array of characters ordered by pixel brightness
+ */
+ private function getOrderedChars():Array
+ {
+ // Create an array containing character and its brightness
+ var order:Array = new Array();
+ for (var i:int = MIN_ASCII_CHAR; i < MAX_ASCII_CHAR; i++)
+ {
+ var c:String = String.fromCharCode(i);
+ order.push( { char:c, level:getCharBrightness(c) } );
+ }
+
+ // Sort the characters in order of descending brightness
+ order.sortOn("level", Array.NUMERIC | Array.DESCENDING);
+
+ // Return a new array containing only the characters in order
+ var list:Array = new Array();
+ for (i = order.length; i--; ) list.push(order[i].char);
+ return list;
+ }
+
+ /**
+ * Calculates the pixel brightness a character
+ *
+ * @param char The single ASCII character to test for brightness level
+ * @return A number between 0 and 1 indicating the amount of brightness
+ */
+ private function getCharBrightness(char:String):Number
+ {
+ // Create a temporary textfield to hold this character
+ var tf:TextField = new TextField();
+ tf.defaultTextFormat = new TextFormat(FONT_NAME, FONT_SIZE, 0x000000);
+ tf.text = char.charAt();
+ tf.autoSize = TextFieldAutoSize.LEFT;
+
+ // Determine the width and height of this character
+ var charWidth:int = Math.ceil(tf.width);
+ var charHeight:int = Math.ceil(tf.height);
+
+ // Create a temporary bitmap data to draw this character into
+ var charBitmap:BitmapData = new BitmapData(charWidth, charHeight, false, 0xFFFFFFFF);
+ charBitmap.draw(tf);
+
+ // Loop through each pixel in this character's bitmap data
+ var level:int = 0;
+ for (var y:int = charHeight; y--; )
+ {
+ for (var x:int = charWidth; x--; )
+ {
+ // If this pixel is bright enough, add it to the overall brightness level
+ if (charBitmap.getPixel(x, y) > 0x808080) level++;
+ }
+ }
+
+ // Return the brightness level as a percentage of the whole character area
+ return level / (charWidth * charHeight);
+ }
+
+ /**
+ * Converts a colour value to an averaged monochrome (greyscale) value
+ *
+ * @param col The colour to convert to monochrome
+ * @return The averaged monochrome value
+ */
+ private function getMonochrome(col:uint):uint
+ {
+ // Add the red, green and blue components together and return the average
+ return 0xFF - (((col >> 16) & 0xFF) + ((col >> 8) & 0xFF) + (col & 0xFF)) / 3;
+ }
+
+ /**
+ * Draws the ASCII effect
+ */
+ override public function draw():void
+ {
+ // Generate a lower resolution bitmap data to sample pixels from
+ smallBitmap.draw(source, smallMatrix, color);
+
+ // Create the ASCII textfield from each pixel
+ var str:String = "";
+ for (var y:int = 0; y < charsY; y++)
+ {
+ for (var x:int = 0; x < charsX; x++)
+ {
+ // Get the monochrome pixel value and convert it to an ASCII character
+ str += chars[int(getMonochrome(smallBitmap.getPixel(x, y)) / 0xFF * total)];
+ }
+ str += "\r\n"; // New line
+ }
+
+ // Draw the new ASCII textfield into the text bitmap data with a blurred background glow
+ textfield.text = str;
+ textBitmap.fillRect(rect, 0xFF000000);
+ textBitmap.draw(textfield, textMatrix);
+ sourceBitmap.applyFilter(textBitmap, rect, point, blur);
+ sourceBitmap.draw(textBitmap, null, null, BlendMode.ADD);
+ targetBitmap.draw(sourceBitmap, flipMatrix);
+ }
+
+ /**
+ * Removes the ASCII effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ smallBitmap.dispose();
+ smallBitmap = null;
+ textBitmap.dispose();
+ textBitmap = null;
+ textfield = null;
+ chars = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/pixel/HalftoneDot.as b/webcam/com/neave/webcam/effects/pixel/HalftoneDot.as new file mode 100755 index 0000000..4f4fb40 --- /dev/null +++ b/webcam/com/neave/webcam/effects/pixel/HalftoneDot.as @@ -0,0 +1,33 @@ +/**
+ * Neave Webcam // Halftone Dot
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+
+ final internal class HalftoneDot extends Shape
+ {
+ /**
+ * Draws a halftone dot shape to be used with the halftone effect
+ *
+ * @param x The position of the dot on the x-axis
+ * @param y The position of the dot on the y-axis
+ * @param radius The radius of the dot
+ */
+ public function HalftoneDot(x:Number = 0, y:Number = 0, radius:Number = 1)
+ {
+ this.x = x;
+ this.y = y;
+ graphics.beginFill(0x000000);
+ graphics.drawCircle(0, 0, radius);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/pixel/HalftoneEffect.as b/webcam/com/neave/webcam/effects/pixel/HalftoneEffect.as new file mode 100755 index 0000000..0b9cf3c --- /dev/null +++ b/webcam/com/neave/webcam/effects/pixel/HalftoneEffect.as @@ -0,0 +1,135 @@ +/**
+ * Neave Webcam // Halftone Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class HalftoneEffect extends AbstractEffect
+ {
+ private var dotsWide:int;
+ private var invert:Boolean;
+ private var smallBitmap:BitmapData;
+ private var smallMatrix:Matrix;
+ private var halftone:Sprite;
+ private var dotsX:int;
+ private var dotsY:int;
+ private var size:Number;
+
+ /**
+ * Creates a halftone effect where each pixel is drawn as a variably-sized black dot, as used in the printing process
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param dotsWide The number of dots to use in width
+ * @param invert Inverts the halftone effect so bright pixels create large dots
+ */
+ public function HalftoneEffect(source:IBitmapDrawable, targetBitmap:BitmapData, dotsWide:int = 40, invert:Boolean = false)
+ {
+ super(source, targetBitmap, "Halftone");
+ this.dotsWide = dotsWide < 1 ? 1: dotsWide;
+ this.invert = invert;
+
+ createHalftone();
+ }
+
+ /**
+ * Sets up the halftone effect
+ */
+ private function createHalftone():void
+ {
+ // Increase contrast
+ color = new ColorTransform(1.5, 1.5, 1.5, 1, -50, -50, -50);
+
+ // Create a smaller, lower resolution bitmap to sample pixels from
+ smallBitmap = new BitmapData(dotsWide, Math.round(dotsWide * rect.height / rect.width), false, 0xFF000000);
+ dotsX = smallBitmap.width;
+ dotsY = smallBitmap.height;
+ smallMatrix = new Matrix();
+ smallMatrix.scale(dotsX / rect.width, dotsY / rect.height);
+ size = rect.width / dotsX;
+
+ // Create a sprite containing all the halftone dots needed
+ halftone = new Sprite();
+ for (var y:int = dotsY; y--; )
+ {
+ for (var x:int = dotsX; x--; )
+ {
+ // Position each halftone dot, alternating the y-axis position between on pixel and halfway between pixels
+ halftone.addChild(new HalftoneDot((x + 0.25 + (y % 2) * 0.5) * size, (y + 0.5) * size, size));
+ }
+ }
+ }
+
+ /**
+ * Converts a colour value to an averaged monochrome (greyscale) value
+ *
+ * @param col The colour to convert to monochrome
+ * @param inv Whether to invert the monochrome value
+ * @return The averaged monochrome value
+ */
+ private function getMonochrome(col:uint, inv:Boolean):uint
+ {
+ // Add the red, green and blue components together and return the average
+ var mono:uint = (((col >> 16) & 0xFF) + ((col >> 8) & 0xFF) + (col & 0xFF)) / 3;
+ if (inv) return mono;
+ else return 0xFF - mono;
+ }
+
+ /**
+ * Draws the halftone effect
+ */
+ override public function draw():void
+ {
+ // Generate a lower resolution bitmap data to sample pixels from
+ smallBitmap.draw(source, smallMatrix, color);
+
+ // Create the halftone dots from each pixel
+ var n:int = 0;
+ for (var y:int = dotsY; y--; )
+ {
+ for (var x:int = dotsX; x--; )
+ {
+ // Average this pixel's colour to a greyscale value
+ var w:Number = getMonochrome(smallBitmap.getPixel(x, y), invert) / 0xFF * Math.SQRT2 * size;
+
+ // Set this dot's size, alternating the y-axis position between on pixel and halfway between pixels
+ var d:HalftoneDot = halftone.getChildAt(n) as HalftoneDot;
+ d.width = d.height = (y % 2 == 0 || n == 0) ? w : (w + halftone.getChildAt(n - 1).width) / 2; // Average pixel values if this y-axis position is between pixels
+ n++;
+ }
+ }
+
+ // Draw the new halftone dots
+ targetBitmap.lock();
+ targetBitmap.fillRect(rect, 0xFFFFFFFF);
+ targetBitmap.draw(halftone);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the halftone effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the halftone dots
+ for (var i:int = dotsX * dotsY; i--; ) halftone.removeChildAt(i);
+ halftone = null;
+
+ smallBitmap.dispose();
+ smallBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/pixel/PixelateEffect.as b/webcam/com/neave/webcam/effects/pixel/PixelateEffect.as new file mode 100755 index 0000000..8ff94d5 --- /dev/null +++ b/webcam/com/neave/webcam/effects/pixel/PixelateEffect.as @@ -0,0 +1,75 @@ +/**
+ * Neave Webcam // Pixelate Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class PixelateEffect extends AbstractEffect
+ {
+ private var pixelsWide:int;
+ private var smallBitmap:BitmapData;
+ private var targetMatrix:Matrix;
+
+ /**
+ * Creates a low-resolution effect where pixels appear large
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param pixelsWide The number of pixels to use in width
+ */
+ public function PixelateEffect(source:IBitmapDrawable, targetBitmap:BitmapData, pixelsWide:int = 20)
+ {
+ super(source, targetBitmap, "Pixelate");
+ this.pixelsWide = pixelsWide < 1 ? 1 : pixelsWide;
+
+ createPixelate();
+ }
+
+ /**
+ * Sets up the pixelate effect
+ */
+ private function createPixelate():void
+ {
+ // Create a low resolution bitmap data
+ smallBitmap = new BitmapData(pixelsWide, Math.round(pixelsWide * rect.height / rect.width), false, 0xFF000000);
+
+ // Set up scaling of bitmaps from large to small to large again
+ var sx:Number = smallBitmap.width / rect.width;
+ var sy:Number = smallBitmap.height / rect.height;
+ sourceMatrix.scale(sx, sy);
+ targetMatrix = new Matrix();
+ targetMatrix.scale(1 / sx, 1 / sy);
+ }
+
+ /**
+ * Draws the pixelate effect
+ */
+ override public function draw():void
+ {
+ // Resize small then resize large
+ smallBitmap.draw(source, sourceMatrix);
+ targetBitmap.draw(smallBitmap, targetMatrix);
+ }
+
+ /**
+ * Removes the pixelate effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ smallBitmap.dispose();
+ smallBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/pixel/RGBEffect.as b/webcam/com/neave/webcam/effects/pixel/RGBEffect.as new file mode 100755 index 0000000..4d2b2ff --- /dev/null +++ b/webcam/com/neave/webcam/effects/pixel/RGBEffect.as @@ -0,0 +1,126 @@ +/**
+ * Neave Webcam // Red Green Blue Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class RGBEffect extends AbstractEffect
+ {
+ private const COLORS:Array = [0xFF0000, 0x00FF00, 0x0000FF];
+
+ private var pixelsWide:int;
+ private var smallBitmap:BitmapData;
+ private var smallMatrix:Matrix;
+ private var pixels:Sprite;
+ private var pixelsX:int;
+ private var pixelsY:int;
+ private var size:Number;
+
+ /**
+ * Creates a low-resolution effect where each pixel is split into its red, green and blue components
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param pixelsWide The number of pixels to use in width
+ */
+ public function RGBEffect(source:IBitmapDrawable, targetBitmap:BitmapData, pixelsWide:int = 40)
+ {
+ super(source, targetBitmap, "RGB");
+ this.pixelsWide = pixelsWide < 3 ? 3 : pixelsWide;
+
+ createRGB();
+ }
+
+ /**
+ * Sets up the RGB effect
+ */
+ private function createRGB():void
+ {
+ // Create a smaller, lower resolution bitmap to sample pixels from
+ smallBitmap = new BitmapData(pixelsWide, Math.round(pixelsWide * rect.height / rect.width), false, 0xFF000000);
+ pixelsX = smallBitmap.width;
+ pixelsY = smallBitmap.height;
+ smallMatrix = new Matrix();
+ smallMatrix.scale(pixelsX / rect.width, pixelsY / rect.height);
+ size = rect.width / pixelsX;
+
+ // Create a sprite containing all the RGB pixels needed
+ pixels = new Sprite();
+ for (var y:int = pixelsY; y--; )
+ {
+ for (var x:int = pixelsX; x--; )
+ {
+ // Position each RGB pixel and set its colour to either red, green or blue
+ pixels.addChild(new RGBPixel((x + 0.5) * size, (y + 0.5) * size, COLORS[x % 3], size));
+ }
+ }
+ }
+
+ /**
+ * Draws the RGB effect
+ */
+ override public function draw():void
+ {
+ // Generate a lower resolution bitmap data to sample pixels from
+ smallBitmap.draw(source, smallMatrix, color);
+
+ // Create the RGB pixels from each pixel
+ var n:int = 0;
+ for (var y:int = pixelsY; y--; )
+ {
+ for (var x:int = pixelsX; x--; )
+ {
+ // Set the brightness of this RGB pixel
+ var c:uint = smallBitmap.getPixel(x, y);
+ var p:RGBPixel = pixels.getChildAt(n++) as RGBPixel;
+ switch (x % 3)
+ {
+ case 0: // Red
+ p.alpha = ((c >> 16) & 0xFF) / 0xFF;
+ break;
+
+ case 1: // Green
+ p.alpha = ((c >> 8) & 0xFF) / 0xFF;
+ break;
+
+ case 2: // Blue
+ p.alpha = (c & 0xFF) / 0xFF;
+ break;
+ }
+ }
+ }
+
+ // Draw the new RGB pixels
+ targetBitmap.lock();
+ targetBitmap.fillRect(rect, 0xFF000000);
+ targetBitmap.draw(pixels);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the RGB effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the pixels
+ for (var i:int = pixelsX * pixelsY; i--; ) pixels.removeChildAt(i);
+ pixels = null;
+
+ smallBitmap.dispose();
+ smallBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/com/neave/webcam/effects/pixel/RGBPixel.as b/webcam/com/neave/webcam/effects/pixel/RGBPixel.as new file mode 100755 index 0000000..ababb10 --- /dev/null +++ b/webcam/com/neave/webcam/effects/pixel/RGBPixel.as @@ -0,0 +1,34 @@ +/**
+ * Neave Webcam // Red Green Blue Pixel
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+
+ final internal class RGBPixel extends Shape
+ {
+ /**
+ * Draws a simple square graphic to be used with the RGB effect
+ *
+ * @param x The position of the pixel on the x-axis
+ * @param y The position of the pixel on the y-axis
+ * @param color The colour of the pixel
+ * @param size The size (width and height) of the pixel
+ */
+ public function RGBPixel(x:int = 0, y:int = 0, color:uint = 0, size:Number = 1)
+ {
+ this.x = x - size / 2;
+ this.y = y - size / 2;
+ graphics.beginFill(color);
+ graphics.drawRect(0, 0, size, size);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/media/NeaveCamera.as b/webcam/media/NeaveCamera.as new file mode 100755 index 0000000..f401af8 --- /dev/null +++ b/webcam/media/NeaveCamera.as @@ -0,0 +1,81 @@ +/**
+ * Neave Camera
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.media
+{
+ import flash.events.*;
+ import flash.media.*;
+ import flash.system.*;
+
+ public class NeaveCamera
+ {
+ /**
+ * The requested width of the camera object
+ */
+ static public var CAMERA_WIDTH:int = 320;
+
+ /**
+ * The requested height of the camera object
+ */
+ static public var CAMERA_HEIGHT:int = 240;
+
+ static private var cam:Camera;
+
+ public function NeaveCamera() { }
+
+ /**
+ * Sets up and returns the camera object
+ *
+ * @return A camera object
+ */
+ static public function getCamera():Camera
+ {
+ // Return the same camera if it has been successfully requested before
+ if (cam != null)
+ {
+ if (cam.muted) Security.showSettings(SecurityPanel.PRIVACY);
+ return cam;
+ }
+
+ // Get the camera
+ cam = Camera.getCamera();
+ if (cam != null)
+ {
+ // Set properties if a camera was found
+ cam.setMode(CAMERA_WIDTH, CAMERA_HEIGHT, 30, true);
+ cam.addEventListener(StatusEvent.STATUS, NeaveCamera.statusListener);
+ return cam;
+ }
+ else
+ {
+ // No camera found
+ Security.showSettings(SecurityPanel.CAMERA);
+ return new Camera();
+ }
+ }
+
+ /**
+ * Whether the camera object is available or not
+ */
+ static public function get muted():Boolean
+ {
+ return cam == null || cam.muted || cam.name == null || cam.width == 0;
+ }
+
+ /**
+ * Camera status response
+ */
+ static private function statusListener(e:StatusEvent):void
+ {
+ if (e.code == "Camera.Unmuted") Security.showSettings(SecurityPanel.CAMERA);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/media/NeaveMicrophone.as b/webcam/media/NeaveMicrophone.as new file mode 100755 index 0000000..6a46ee7 --- /dev/null +++ b/webcam/media/NeaveMicrophone.as @@ -0,0 +1,104 @@ +/**
+ * Neave Microphone
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.media
+{
+ import flash.events.*;
+ import flash.media.*;
+ import flash.system.*;
+ import flash.utils.*;
+
+ public class NeaveMicrophone
+ {
+ static private var mic:Microphone;
+ static private var gainTimer:Timer;
+
+ public function NeaveMicrophone() { }
+
+ /**
+ * Sets up and returns the microphone object
+ *
+ * @return A microphone object
+ */
+ static public function getMicrophone():Microphone
+ {
+ // Return the same microphone if it has been successfully requested before
+ if (mic != null)
+ {
+ if (mic.muted) Security.showSettings(SecurityPanel.PRIVACY);
+ else NeaveMicrophone.startAutoGain();
+ return mic;
+ }
+
+ gainTimer = new Timer(100);
+
+ // Get the microphone
+ mic = Microphone.getMicrophone();
+ if (mic != null)
+ {
+ // Set properties if a microphone was found
+ mic.setLoopBack(true);
+ mic.rate = 44;
+ mic.gain = 25;
+ mic.setSilenceLevel(0);
+ mic.setUseEchoSuppression(true);
+ mic.soundTransform = new SoundTransform(0); // Mute microphone from sounding on speakers
+ mic.addEventListener(StatusEvent.STATUS, NeaveMicrophone.statusListener);
+
+ return mic;
+ }
+ else
+ {
+ // No microphone found
+ Security.showSettings(SecurityPanel.MICROPHONE);
+ return new Microphone();
+ }
+ }
+
+ /**
+ * Microphone status response
+ */
+ static private function statusListener(e:StatusEvent):void
+ {
+ if (e.code == "Microphone.Unmuted") NeaveMicrophone.startAutoGain();
+ else NeaveMicrophone.stopAutoGain();
+ }
+
+ /**
+ * Set up gain control
+ */
+ static public function startAutoGain():void
+ {
+ gainTimer.start();
+ if (!gainTimer.hasEventListener(TimerEvent.TIMER)) gainTimer.addEventListener(TimerEvent.TIMER, setGain);
+ }
+
+ /**
+ * Stop gain control
+ */
+ static public function stopAutoGain():void
+ {
+ gainTimer.stop();
+ gainTimer.reset();
+ gainTimer.removeEventListener(TimerEvent.TIMER, setGain);
+ }
+
+ /**
+ * Dynamically adjust the microphone's gain value
+ */
+ static private function setGain(e:TimerEvent):void
+ {
+ if (mic.activityLevel < 15) mic.gain = 30;
+ else if (mic.activityLevel > 90) mic.gain = 20;
+ else mic.gain = 25;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam.swf b/webcam/webcam.swf Binary files differnew file mode 100644 index 0000000..7999270 --- /dev/null +++ b/webcam/webcam.swf diff --git a/webcam/webcam/NeaveWebcam.as b/webcam/webcam/NeaveWebcam.as new file mode 100755 index 0000000..811446b --- /dev/null +++ b/webcam/webcam/NeaveWebcam.as @@ -0,0 +1,196 @@ +/**
+ * Neave Webcam ...play with webcam effects
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * @author Paul Neave
+ * @version 1.0.0
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam
+{
+ import flash.display.*;
+ import flash.events.*;
+ import flash.media.*;
+ import flash.ui.*;
+ import com.neave.media.*;
+ import com.neave.webcam.effects.*;
+
+ public class NeaveWebcam extends Sprite
+ {
+ // Main variables
+ private var camera:Camera;
+ private var video:Video;
+ private var videoBitmap:Bitmap;
+ private var videoContainer:Sprite;
+ private var uiEnabled:Boolean;
+
+ /**
+ * Manages the webcam effects
+ */
+ public var effects:EffectsManager;
+
+ /**
+ * Creates a new instance of Neave Webcam
+ *
+ * @param camera The camera object to use to create the webcam effects
+ * @param interactive Enable mouse click or arrow keys to change the webcam effect
+ */
+ public function NeaveWebcam(camera:Camera, interactive:Boolean = true)
+ {
+ this.camera = camera;
+
+ initVideo();
+ initEffects();
+
+ this.interactive = interactive;
+ }
+
+ /**
+ * Sets up the main video object
+ */
+ private function initVideo():void
+ {
+ // Video dimensions must be 320x240 or higher
+ var w:int = camera.width < NeaveCamera.CAMERA_WIDTH ? NeaveCamera.CAMERA_WIDTH : camera.width;
+ var h:int = camera.height < NeaveCamera.CAMERA_HEIGHT ? NeaveCamera.CAMERA_HEIGHT : camera.height;
+
+ // Attach the camera object a video object
+ video = new Video(w, h);
+ video.attachCamera(camera);
+
+ // Create a bitmap object for the video effect, flipping to create a mirror image
+ videoBitmap = new Bitmap(new BitmapData(w, h, false, 0xFF000000), PixelSnapping.AUTO, false);
+ videoBitmap.scaleX = -1;
+ videoBitmap.x = w;
+
+ // Create a sprite to hold the bitmap
+ videoContainer = new Sprite();
+ videoContainer.addChild(videoBitmap);
+ addChild(videoContainer);
+ }
+
+ /**
+ * Sets up the webcam effects for the video object
+ */
+ private function initEffects():void
+ {
+ // Set up the effects manager for this video object
+ effects = new EffectsManager(video, videoBitmap.bitmapData);
+ paused = false;
+ }
+
+ /**
+ * Enable mouse click or arrow keys to change the webcam effect
+ */
+ public function set interactive(i:Boolean):void
+ {
+ uiEnabled = i;
+
+ if (uiEnabled)
+ {
+ // Arrow keys select previous or next webcam effect
+ addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
+
+ // Clicking on the video selects the next webcam effect
+ videoContainer.addEventListener(MouseEvent.CLICK, videoClickListener);
+ videoContainer.buttonMode = true;
+ }
+ else
+ {
+ // Remove interactivity
+ removeEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
+ videoContainer.removeEventListener(MouseEvent.CLICK, videoClickListener);
+ videoContainer.buttonMode = false;
+ }
+ }
+
+ /**
+ * Moves to the next webcam effect on mouse click
+ */
+ private function videoClickListener(e:MouseEvent):void
+ {
+ if (paused || camera.muted || camera.width == 0) return;
+
+ effects.nextEffect();
+ }
+
+ /**
+ * Moves to the next or previous webcam effect when the arrow keys are pressed
+ */
+ private function keyDownListener(e:KeyboardEvent):void
+ {
+ if (paused || camera.muted || camera.width == 0) return;
+
+ switch (e.keyCode)
+ {
+ case Keyboard.LEFT:
+ effects.previousEffect();
+ break;
+
+ case Keyboard.RIGHT:
+ effects.nextEffect();
+ break;
+ }
+ }
+
+ /**
+ * The bitmap data containing the current webcam effect
+ */
+ public function get effectBitmap():BitmapData
+ {
+ return videoBitmap.bitmapData;
+ }
+
+ /**
+ * Pause or resume the current webcam effect
+ */
+ public function set paused(p:Boolean):void
+ {
+ if (p == paused) return;
+
+ // Pause or resume updating the current webcam effect every frame
+ if (p) removeEventListener(Event.ENTER_FRAME, update);
+ else addEventListener(Event.ENTER_FRAME, update);
+ }
+
+ /**
+ * Pause or resume the current webcam effect
+ */
+ public function get paused():Boolean
+ {
+ return !hasEventListener(Event.ENTER_FRAME);
+ }
+
+ /**
+ * Removes the webcam and all other referenced objects
+ */
+ public function destroy():void
+ {
+ interactive = false;
+ paused = true;
+ effects.destroy();
+ videoContainer.removeChild(videoBitmap);
+ videoBitmap.bitmapData.dispose();
+ videoBitmap.bitmapData = null;
+ videoBitmap = null;
+ removeChild(videoContainer);
+ videoContainer = null;
+ video = null;
+ camera = null;
+ }
+
+ /**
+ * Updates the current webcam effect
+ */
+ private function update(e:Event):void
+ {
+ effects.update();
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/AbstractEffect.as b/webcam/webcam/effects/AbstractEffect.as new file mode 100755 index 0000000..a0fb241 --- /dev/null +++ b/webcam/webcam/effects/AbstractEffect.as @@ -0,0 +1,81 @@ +/**
+ * Neave Webcam // Abstract Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects
+{
+ import flash.display.*;
+ import flash.geom.*;
+
+ public class AbstractEffect
+ {
+ protected var source:IBitmapDrawable;
+ protected var targetBitmap:BitmapData;
+ protected var name:String;
+ protected var sourceBitmap:BitmapData;
+ protected var sourceMatrix:Matrix;
+ protected var rect:Rectangle;
+ protected var point:Point;
+ protected var color:ColorTransform;
+
+ /**
+ * An abstract effect class, not to be instantiated
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param name The proper name of the effect
+ */
+ public function AbstractEffect(source:IBitmapDrawable, targetBitmap:BitmapData, name:String = "")
+ {
+ this.source = source;
+ this.targetBitmap = targetBitmap;
+ this.name = name;
+
+ createEffect();
+ }
+
+ /**
+ * Sets up the effect
+ */
+ private function createEffect():void
+ {
+ sourceBitmap = targetBitmap.clone();
+ sourceMatrix = new Matrix();
+ rect = targetBitmap.rect;
+ point = new Point();
+ color = new ColorTransform();
+ }
+
+ /**
+ * The proper name of the effect
+ */
+ public function get effectName():String
+ {
+ return name;
+ }
+
+ /**
+ * Draws the effect
+ */
+ public function draw():void
+ {
+ sourceBitmap.draw(source, sourceMatrix, color);
+ }
+
+ /**
+ * Removes the effect and all other referenced objects
+ */
+ public function destroy():void
+ {
+ sourceBitmap.dispose();
+ sourceBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/EffectEvent.as b/webcam/webcam/effects/EffectEvent.as new file mode 100755 index 0000000..134b792 --- /dev/null +++ b/webcam/webcam/effects/EffectEvent.as @@ -0,0 +1,23 @@ +package com.neave.webcam.effects
+{
+ import flash.events.*;
+
+ public class EffectEvent extends Event
+ {
+ public static const NEW_EFFECT:String = "newEffect";
+
+ private var _effectType:int;
+
+ public function EffectEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, effectType:int = 0)
+ {
+ super(type, bubbles, cancelable);
+
+ _effectType = effectType;
+ }
+
+ public function get effectType():int
+ {
+ return _effectType;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/EffectType.as b/webcam/webcam/effects/EffectType.as new file mode 100755 index 0000000..af5abea --- /dev/null +++ b/webcam/webcam/effects/EffectType.as @@ -0,0 +1,55 @@ +/**
+ * Neave Webcam // Effects Type
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects
+{
+ final public class EffectType
+ {
+ static public const NORMAL :int = 0;
+ static public const MIRROR_LEFT :int = 1;
+ static public const MIRROR_RIGHT :int = 2;
+ static public const MIRROR_TOP :int = 3;
+ static public const MIRROR_BOTTOM :int = 4;
+ static public const MIRROR_INVERSE :int = 5;
+ static public const MIRROR_QUAD :int = 6;
+ static public const UPSIDE_DOWN :int = 7;
+ static public const DIVIDE :int = 8;
+ static public const FILMSTRIP :int = 9;
+ static public const FRAGMENT :int = 10;
+ static public const GHOST :int = 11;
+ static public const TRAIL :int = 12;
+ static public const BULGE :int = 13;
+ static public const FISHEYE :int = 14;
+ static public const FISHBOWL :int = 15;
+ static public const DENT :int = 16;
+ static public const SQUEEZE :int = 17;
+ static public const WATER :int = 18;
+ static public const FIRE :int = 19;
+ static public const SNOW :int = 20;
+ static public const STEAM :int = 21;
+ static public const SWARM :int = 22;
+ static public const PIXELATE :int = 23;
+ static public const RGB :int = 24;
+ static public const HALFTONE :int = 25;
+ static public const MONOCHROME :int = 26;
+ static public const SEPIA :int = 27;
+ static public const RAINBOW :int = 28;
+ static public const ASCII :int = 29;
+ static public const X_RAY :int = 30;
+ static public const WARHOL :int = 31;
+ static public const GLOW :int = 32;
+ static public const SLIT_SCAN :int = 33;
+
+ static public const TOTAL_EFFECTS :int = 33;
+
+ public function EffectType() { }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/EffectsManager.as b/webcam/webcam/effects/EffectsManager.as new file mode 100755 index 0000000..57eac59 --- /dev/null +++ b/webcam/webcam/effects/EffectsManager.as @@ -0,0 +1,156 @@ +/**
+ * Neave Webcam // Effects Manager
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects
+{
+ import flash.display.*;
+ import flash.events.*;
+ import com.neave.webcam.effects.color.*;
+ import com.neave.webcam.effects.delay.*;
+ import com.neave.webcam.effects.displace.*;
+ import com.neave.webcam.effects.mirror.*;
+ import com.neave.webcam.effects.motion.*;
+ import com.neave.webcam.effects.pixel.*;
+
+ public class EffectsManager extends EventDispatcher
+ {
+ private var source:IBitmapDrawable;
+ private var targetBitmap:BitmapData;
+ private var effect:AbstractEffect;
+ private var chosenEffect:int;
+
+ /**
+ * Manages all of the webcam effects
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function EffectsManager(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ this.source = source;
+ this.targetBitmap = targetBitmap;
+
+ // Start with the normal effect
+ effectType = EffectType.NORMAL;
+ }
+
+ /**
+ * Sets the effect to the next effect in the EffectType class
+ */
+ public function nextEffect():void
+ {
+ effectType = chosenEffect + 1;
+ }
+
+ /**
+ * Sets the effect to the previous effect in the EffectType class
+ */
+ public function previousEffect():void
+ {
+ effectType = chosenEffect - 1;
+ }
+
+ /**
+ * An integer representing the current effect in the EffectType class
+ */
+ public function set effectType(type:int):void
+ {
+ // Remove the previous effect
+ if (effect != null) effect.destroy();
+
+ // Wrap the chosen effect within the total effects available
+ if (type > EffectType.TOTAL_EFFECTS) type = 0;
+ if (type < 0) type = EffectType.TOTAL_EFFECTS;
+
+ // Set the effect
+ switch (type)
+ {
+ case EffectType.MIRROR_LEFT: effect = new LeftMirrorEffect (source, targetBitmap); break;
+ case EffectType.MIRROR_RIGHT: effect = new RightMirrorEffect (source, targetBitmap); break;
+ case EffectType.MIRROR_TOP: effect = new TopMirrorEffect (source, targetBitmap); break;
+ case EffectType.MIRROR_BOTTOM: effect = new BottomMirrorEffect (source, targetBitmap); break;
+ case EffectType.MIRROR_INVERSE: effect = new InverseMirrorEffect (source, targetBitmap); break;
+ case EffectType.MIRROR_QUAD: effect = new QuadMirrorEffect (source, targetBitmap); break;
+ case EffectType.UPSIDE_DOWN: effect = new UpsideDownEffect (source, targetBitmap); break;
+ case EffectType.DIVIDE: effect = new DivideEffect (source, targetBitmap); break;
+ case EffectType.FILMSTRIP: effect = new FilmstripEffect (source, targetBitmap); break;
+ case EffectType.FRAGMENT: effect = new FragmentEffect (source, targetBitmap); break;
+ case EffectType.GHOST: effect = new GhostEffect (source, targetBitmap); break;
+ case EffectType.TRAIL: effect = new TrailEffect (source, targetBitmap); break;
+ case EffectType.BULGE: effect = new BulgeEffect (source, targetBitmap); break;
+ case EffectType.FISHEYE: effect = new FisheyeEffect (source, targetBitmap); break;
+ case EffectType.FISHBOWL: effect = new FishbowlEffect (source, targetBitmap); break;
+ case EffectType.DENT: effect = new DentEffect (source, targetBitmap); break;
+ case EffectType.SQUEEZE: effect = new SqueezeEffect (source, targetBitmap); break;
+ case EffectType.WATER: effect = new WaterEffect (source, targetBitmap); break;
+ case EffectType.FIRE: effect = new FireEffect (source, targetBitmap); break;
+ case EffectType.SNOW: effect = new SnowEffect (source, targetBitmap); break;
+ case EffectType.STEAM: effect = new SteamEffect (source, targetBitmap); break;
+ case EffectType.SWARM: effect = new SwarmEffect (source, targetBitmap); break;
+ case EffectType.PIXELATE: effect = new PixelateEffect (source, targetBitmap); break;
+ case EffectType.RGB: effect = new RGBEffect (source, targetBitmap); break;
+ case EffectType.HALFTONE: effect = new HalftoneEffect (source, targetBitmap); break;
+ case EffectType.MONOCHROME: effect = new MonochromeEffect (source, targetBitmap); break;
+ case EffectType.SEPIA: effect = new SepiaEffect (source, targetBitmap); break;
+ case EffectType.RAINBOW: effect = new RainbowEffect (source, targetBitmap); break;
+ case EffectType.ASCII: effect = new ASCIIEffect (source, targetBitmap); break;
+ case EffectType.X_RAY: effect = new XRayEffect (source, targetBitmap); break;
+ case EffectType.WARHOL: effect = new WarholEffect (source, targetBitmap); break;
+ case EffectType.GLOW: effect = new GlowEffect (source, targetBitmap); break;
+ case EffectType.SLIT_SCAN: effect = new SlitScanEffect (source, targetBitmap); break;
+ case EffectType.NORMAL:
+ default:
+ // Use a normal effect if the passed effect type is not valid
+ type = EffectType.NORMAL;
+ effect = new NormalEffect(source, targetBitmap);
+ break;
+ }
+
+ // Remember the chosen effect
+ chosenEffect = type;
+
+ // Tell anything listening that a new effect has been chosen
+ dispatchEvent(new EffectEvent(EffectEvent.NEW_EFFECT, false, false, chosenEffect));
+ }
+
+ /**
+ * An integer representing the current effect in the EffectType class
+ */
+ public function get effectType():int
+ {
+ return chosenEffect;
+ }
+
+ /**
+ * The proper name of the current effect
+ */
+ public function get effectName():String
+ {
+ return effect.effectName;
+ }
+
+ /**
+ * Updates the appearance of the current effect
+ */
+ public function update():void
+ {
+ effect.draw();
+ }
+
+ /**
+ * Removes the current effect
+ */
+ public function destroy():void
+ {
+ effect.destroy();
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/NormalEffect.as b/webcam/webcam/effects/NormalEffect.as new file mode 100755 index 0000000..b97e896 --- /dev/null +++ b/webcam/webcam/effects/NormalEffect.as @@ -0,0 +1,38 @@ +/**
+ * Neave Webcam // Normal Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects
+{
+ import flash.display.*;
+
+ public class NormalEffect extends AbstractEffect
+ {
+ /**
+ * Creates a normal effect for copying the source object into the target bitmap data without modification
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function NormalEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Normal");
+ }
+
+ /**
+ * Draws the normal effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/color/GlowEffect.as b/webcam/webcam/effects/color/GlowEffect.as new file mode 100755 index 0000000..5c96e71 --- /dev/null +++ b/webcam/webcam/effects/color/GlowEffect.as @@ -0,0 +1,68 @@ +/**
+ * Neave Webcam // Glow Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class GlowEffect extends AbstractEffect
+ {
+ private var edge:ConvolutionFilter;
+ private var blur:BlurFilter;
+
+ /**
+ * Creates a high constrast glow effect around surface edges
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function GlowEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Glow");
+
+ createGlow();
+ }
+
+ /**
+ * Sets up the glow effect
+ */
+ private function createGlow():void
+ {
+ // Increase contrast
+ color = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Set up a large horizontal edge convoluton filter
+ var m:Array =
+ [
+ -100, -100, -100,
+ 100, 100, 100,
+ 0, 0, 0
+ ];
+ edge = new ConvolutionFilter(3, 3, m, 9);
+
+ // Blur the edges to create a smooth glow
+ blur = new BlurFilter(8, 8, 2);
+ }
+
+ /**
+ * Draws the glow effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ sourceBitmap.applyFilter(sourceBitmap, rect, point, blur);
+ targetBitmap.applyFilter(sourceBitmap, rect, point, edge);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/color/MonochromeEffect.as b/webcam/webcam/effects/color/MonochromeEffect.as new file mode 100755 index 0000000..ed14de9 --- /dev/null +++ b/webcam/webcam/effects/color/MonochromeEffect.as @@ -0,0 +1,61 @@ +/**
+ * Neave Webcam // Monochrome (Black & White) Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class MonochromeEffect extends AbstractEffect
+ {
+ private var monochrome:ColorMatrixFilter;
+
+ /**
+ * Creates a high contrast black and white monochrome effect
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function MonochromeEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Black & White");
+
+ createMonochrome();
+ }
+
+ /**
+ * Sets up the monochrome effect
+ */
+ private function createMonochrome():void
+ {
+ // Add punch with more contrast
+ color = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Monochrome colour matrix
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Red
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Green
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ monochrome = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the monochrome effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.applyFilter(sourceBitmap, rect, point, monochrome);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/color/RainbowEffect.as b/webcam/webcam/effects/color/RainbowEffect.as new file mode 100755 index 0000000..3b5b70b --- /dev/null +++ b/webcam/webcam/effects/color/RainbowEffect.as @@ -0,0 +1,90 @@ +/**
+ * Neave Webcam // Rainbow Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class RainbowEffect extends AbstractEffect
+ {
+ private var red:Array;
+ private var green:Array;
+ private var blue:Array;
+
+ /**
+ * Creates a psychedelic colour-cycling effect
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function RainbowEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Rainbow");
+
+ createRainbow();
+ }
+
+ /**
+ * Sets up the rainbow effect
+ */
+ private function createRainbow():void
+ {
+ // Add punch with more contrast
+ color = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Set up colour arrays
+ red = new Array(256);
+ green = new Array(256);
+ blue = new Array(256);
+
+ // Populate colour arrays with a curved gradient
+ for (var i:int = 0; i < 256; i++)
+ {
+ red[i] = Math.sin(i / 0xFF * Math.PI) * 0xFF << 16;
+ green[i] = Math.sin(i / 0xFF * Math.PI) * 0xFF << 8;
+ blue[i] = Math.sin(i / 0xFF * Math.PI) * 0xFF;
+ }
+ }
+
+ /**
+ * Draws the rainbow effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ red.push(red.splice(0, 1));
+ green.unshift(green.pop());
+ green.unshift(green.pop());
+ if (Math.random() < 0.5) green.unshift(green.pop());
+ blue.unshift(blue.pop());
+ blue.unshift(blue.pop());
+ blue.unshift(blue.pop());
+ if (Math.random() < 0.5) blue.unshift(blue.pop());
+ if (Math.random() < 0.5) blue.unshift(blue.pop());
+
+ targetBitmap.paletteMap(sourceBitmap, rect, point, red, green, blue);
+ }
+
+ /**
+ * Removes the rainbow effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ red = null;
+ green = null;
+ blue = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/color/SepiaDirt.as b/webcam/webcam/effects/color/SepiaDirt.as new file mode 100755 index 0000000..4b03f65 --- /dev/null +++ b/webcam/webcam/effects/color/SepiaDirt.as @@ -0,0 +1,31 @@ +/**
+ * Neave Webcam // Sepia Dirt
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+
+ final internal class SepiaDirt extends Shape
+ {
+ /**
+ * Creates a black circular shape to be used with the sepia effect
+ *
+ * @param x The position of the dirt on the x-axis
+ * @param y The position of the dirt on the y-axis
+ * @param radius The radius of the dirt
+ */
+ public function SepiaDirt(x:Number = 0, y:Number = 0, radius:Number = 1)
+ {
+ graphics.beginFill(0x000000);
+ graphics.drawCircle(x, y, radius);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/color/SepiaEffect.as b/webcam/webcam/effects/color/SepiaEffect.as new file mode 100755 index 0000000..f7d2ebe --- /dev/null +++ b/webcam/webcam/effects/color/SepiaEffect.as @@ -0,0 +1,90 @@ +/**
+ * Neave Webcam // Sepia Movie Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class SepiaEffect extends AbstractEffect
+ {
+ private var frameStep:int;
+ private var sepia:ColorMatrixFilter;
+ private var count:uint;
+ private var linePos:Number;
+
+ /**
+ * Creates an animated sepia effect like an old projector movie
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param frameStep The number of frames to step over to create a jittery movie effect
+ */
+ public function SepiaEffect(source:IBitmapDrawable, targetBitmap:BitmapData, frameStep:int = 3)
+ {
+ super(source, targetBitmap, "Sepia Movie");
+ this.frameStep = frameStep < 1 ? 1 : frameStep;
+
+ createSepia();
+ }
+
+ /**
+ * Sets up the sepia effect
+ */
+ private function createSepia():void
+ {
+ // Reset variables
+ count = linePos = 0;
+
+ // Sepia colour matrix
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Red
+ m = m.concat([0.246, 0.4838, 0.0902, 0, 10]); // Green
+ m = m.concat([0.15, 0.295, 0.055, 0, 10]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ sepia = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the sepia effect
+ */
+ override public function draw():void
+ {
+ if (count == 0)
+ {
+ super.draw();
+
+ // Tint source bitmap sepia
+ sourceBitmap.applyFilter(sourceBitmap, rect, point, sepia);
+
+ // Create old movie style black vertical line on one side
+ linePos += (Math.random() * rect.width * 0.25 - linePos) * 0.04;
+ if (Math.random() < 0.05) linePos = rect.width;
+ if (Math.random() < 0.05) linePos = rect.width * 0.2;
+ if (Math.random() < 0.5) sourceBitmap.fillRect(new Rectangle(Math.round(linePos), 0, 1, rect.height), 0xFF000000);
+
+ // Create random dirt with one big spot every so often
+ for (var i:int = 4; i--; ) sourceBitmap.draw(new SepiaDirt(Math.random() * rect.width, Math.random() * rect.height, Math.random() < 0.995 ? Math.random() + 0.5 : Math.random() * 10 + 15));
+
+ // Draw source bitmap into target bitmap with a slight flicker
+ var mult:uint = Math.random() * 64 + (255 - 64);
+ targetBitmap.lock();
+ targetBitmap.fillRect(rect, 0xFF000000);
+ targetBitmap.merge(sourceBitmap, rect, point, mult, mult, mult, 0);
+ targetBitmap.unlock();
+ }
+ count++;
+ count %= frameStep;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/color/WarholEffect.as b/webcam/webcam/effects/color/WarholEffect.as new file mode 100755 index 0000000..81f8289 --- /dev/null +++ b/webcam/webcam/effects/color/WarholEffect.as @@ -0,0 +1,99 @@ +/**
+ * Neave Webcam // Andy Warhol Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class WarholEffect extends AbstractEffect
+ {
+ private var smallBitmap:BitmapData;
+ private var pos1:Point;
+ private var pos2:Point;
+ private var pos3:Point;
+ private var pos4:Point;
+
+ /**
+ * Creates an Andy Warhol-style Pop Art effect with four highly constrasted tricolour images
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function WarholEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Andy Warhol");
+
+ createWarhol();
+ }
+
+ /**
+ * Sets up the Warhol effect
+ */
+ private function createWarhol():void
+ {
+ // Create a bitmap quarter the size of the original
+ smallBitmap = new BitmapData(Math.round(rect.width / 2), Math.round(rect.height / 2), false, 0xFF000000);
+ sourceMatrix.scale(0.5, 0.5);
+
+ // Positions of each image
+ pos1 = new Point(0, 0);
+ pos2 = new Point(smallBitmap.width, 0);
+ pos3 = new Point(0, smallBitmap.height);
+ pos4 = new Point(smallBitmap.width, smallBitmap.height);
+ }
+
+ /**
+ * Draws a tricolour (three colour) image from the passed bitmap into the target bitmap data
+ *
+ * @param bitmapData The source bitmap data to draw the tricolour from
+ * @param pos The position to draw tricolour
+ * @param color1 The background colour
+ * @param color2 The middle colour
+ * @param color3 The highlight colour
+ */
+ private function drawTricolor(bitmapData:BitmapData, pos:Point, color1:uint, color2:uint, color3:uint):void
+ {
+ // Limit the pixels in the bitmap data to three colours only
+ targetBitmap.threshold(bitmapData, rect, pos, "<=", 0xFFAAAAAA, color2);
+ targetBitmap.threshold(bitmapData, rect, pos, ">", 0xFFAAAAAA, color3);
+ targetBitmap.threshold(bitmapData, rect, pos, "<", 0xFF555555, color1);
+ }
+
+ /**
+ * Draws the Warhol effect
+ */
+ override public function draw():void
+ {
+ smallBitmap.draw(source, sourceMatrix);
+
+ targetBitmap.lock();
+ drawTricolor(smallBitmap, pos1, 0xFF0080FF, 0xFFFFFF00, 0xFFFF0080);
+ drawTricolor(smallBitmap, pos2, 0xFF202020, 0xFFFF0000, 0xFFFFFFFF);
+ drawTricolor(smallBitmap, pos3, 0xFFA040A0, 0xFFFF9900, 0xFF80C0FF);
+ drawTricolor(smallBitmap, pos4, 0xFF40A000, 0xFFFFFFA0, 0xFFFFA0FF);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the Warhol effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ smallBitmap.dispose();
+ smallBitmap = null;
+ pos1 = pos2 = pos3 = pos4 = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/color/XRayEffect.as b/webcam/webcam/effects/color/XRayEffect.as new file mode 100755 index 0000000..06067bd --- /dev/null +++ b/webcam/webcam/effects/color/XRayEffect.as @@ -0,0 +1,62 @@ +/**
+ * Neave Webcam // X-Ray Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.color
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class XRayEffect extends AbstractEffect
+ {
+ private var cyanWash:ColorMatrixFilter;
+
+ /**
+ * Creates a mock x-ray effect by inverting the image
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function XRayEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "X-Ray");
+
+ createXRay();
+ }
+
+ /**
+ * Sets up the x-ray effect
+ */
+ private function createXRay():void
+ {
+ // Invert the image
+ color = new ColorTransform(-1.5, -1.5, -1.5, 1, 0xFF, 0xFF, 0xFF);
+
+ // Monochrome colour matrix with a cyan tint
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Red
+ m = m.concat([0.3, 0.59, 0.11, 0, 40]); // Green
+ m = m.concat([0.3, 0.59, 0.11, 0, 50]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ cyanWash = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the x-ray effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.applyFilter(sourceBitmap, rect, point, cyanWash);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/delay/DivideEffect.as b/webcam/webcam/effects/delay/DivideEffect.as new file mode 100755 index 0000000..5e9cfee --- /dev/null +++ b/webcam/webcam/effects/delay/DivideEffect.as @@ -0,0 +1,99 @@ +/**
+ * Neave Webcam // Delayed Divide Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class DivideEffect extends AbstractEffect
+ {
+ private var frames:int;
+ private var divideBitmaps:Array;
+ private var divideRect:Rectangle;
+ private var dividePoint:Point;
+
+ /**
+ * Creates a split screen effect where the lower half of the image is delayed
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param frames The number of frames to delay the lower half of the image by
+ */
+ public function DivideEffect(source:IBitmapDrawable, targetBitmap:BitmapData, frames:int = 30)
+ {
+ super(source, targetBitmap, "Delayed Divide");
+ this.frames = frames < 2 ? 2 : frames;
+
+ createDivide();
+ }
+
+ /**
+ * Sets up the divide effect
+ */
+ private function createDivide():void
+ {
+ // Define the lower half area and its top left position
+ divideRect = new Rectangle(0, rect.height / 2, rect.width, rect.height / 2);
+ dividePoint = new Point(0, rect.height / 2);
+
+ // Draw the delayed bitmap into the lower half
+ var m:Matrix = sourceMatrix.clone();
+ m.translate(0, -rect.height / 2);
+
+ // Create an array of bitmaps to store the delayed frames
+ divideBitmaps = new Array();
+ for (var i:int = frames; i--; )
+ {
+ var b:BitmapData = new BitmapData(rect.width, rect.height / 2, false, 0xFF000000);
+ b.draw(source, m, color, null, rect, true); // Start with the current source image
+ divideBitmaps.push(b);
+ }
+ }
+
+ /**
+ * Draws the divide effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through all the delayed frames
+ for (var i:int = frames; i--; )
+ {
+ var b:BitmapData = divideBitmaps[i];
+ if (i == 0) b.copyPixels(sourceBitmap, divideRect, point); // Draw the current source image into frame 0
+ else b.copyPixels(divideBitmaps[i - 1], b.rect, point); // Move the other frames along the array
+ }
+
+ // Draw the final delayed frame into the lower half with the current source image
+ sourceBitmap.copyPixels(divideBitmaps[frames - 1], divideBitmaps[0].rect, dividePoint);
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ }
+
+ /**
+ * Removes the divide effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the frame bitmaps
+ for (var i:int = frames; i--; )
+ {
+ divideBitmaps[i].dispose();
+ divideBitmaps[i] = null;
+ }
+ divideBitmaps = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/delay/FilmstripEffect.as b/webcam/webcam/effects/delay/FilmstripEffect.as new file mode 100755 index 0000000..ce324b1 --- /dev/null +++ b/webcam/webcam/effects/delay/FilmstripEffect.as @@ -0,0 +1,91 @@ +/**
+ * Neave Webcam // Filmstrip Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class FilmstripEffect extends AbstractEffect
+ {
+ private var scale:int;
+ private var total:int;
+ private var filmstrip:Array;
+
+ /**
+ * Creates a grid of delayed images, each delayed by one frame after the previous frame
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param scale The number of images to use along the width and height of the grid
+ */
+ public function FilmstripEffect(source:IBitmapDrawable, targetBitmap:BitmapData, scale:int = 8)
+ {
+ super(source, targetBitmap, "Filmstrip");
+ this.scale = scale < 2 ? 2 : scale;
+
+ createFilmstrip();
+ }
+
+ /**
+ * Sets up the filmstrip effect
+ */
+ private function createFilmstrip():void
+ {
+ // Resize the source to the set scale
+ sourceMatrix.scale(1 / scale, 1 / scale);
+
+ // Create an array of bitmaps to store the delayed frames
+ total = scale * scale;
+ filmstrip = new Array();
+ for (var i:int = total; i--; )
+ {
+ var b:BitmapData = new BitmapData(rect.width / scale, rect.height / scale, false, 0xFF000000);
+ b.draw(source, sourceMatrix, color, null, null, true);
+ filmstrip.push(b);
+ }
+ }
+
+ /**
+ * Draws the filmstrip effect
+ */
+ override public function draw():void
+ {
+ // Loop through all the delayed frames
+ targetBitmap.lock();
+ for (var i:int = total; i--; )
+ {
+ var b:BitmapData = filmstrip[i];
+ if (i == 0) b.draw(source, sourceMatrix, color); // Draw the source at a smaller size into frame 0
+ else b.copyPixels(filmstrip[i - 1], b.rect, point); // Move the other frames along the array
+ targetBitmap.copyPixels(b, b.rect, new Point((scale - (i % scale) - 1) * rect.width / scale, int(i / scale) * rect.height / scale)); // Draw this frame in position
+ }
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the divide effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the filmstrip bitmaps
+ for (var i:int = total; i--; )
+ {
+ filmstrip[i].dispose();
+ filmstrip[i] = null;
+ }
+ filmstrip = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/delay/GhostEffect.as b/webcam/webcam/effects/delay/GhostEffect.as new file mode 100755 index 0000000..35c5787 --- /dev/null +++ b/webcam/webcam/effects/delay/GhostEffect.as @@ -0,0 +1,89 @@ +/**
+ * Neave Webcam // Ghost Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class GhostEffect extends AbstractEffect
+ {
+ private var frames:int;
+ private var ghostBitmaps:Array;
+
+ /**
+ * Creates a ghost effect where the source image is delayed then blended with the current image
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param frames The number of frames to delay the ghost image by
+ */
+ public function GhostEffect(source:IBitmapDrawable, targetBitmap:BitmapData, frames:int = 30)
+ {
+ super(source, targetBitmap, "Ghost");
+ this.frames = frames < 2 ? 2 : frames;
+
+ createGhost();
+ }
+
+ /**
+ * Sets up the ghost effect
+ */
+ private function createGhost():void
+ {
+ // Create an array of bitmaps to store the delayed frames
+ ghostBitmaps = new Array();
+ for (var i:int = frames; i--; )
+ {
+ var b:BitmapData = sourceBitmap.clone();
+ b.draw(source, null, color, null, null, true); // Start with the current source image
+ ghostBitmaps.push(b);
+ }
+ }
+
+ /**
+ * Draws the ghost effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through all the delayed frames
+ for (var i:int = frames; i--; )
+ {
+ var b:BitmapData = ghostBitmaps[i];
+ if (i == 0) b.copyPixels(sourceBitmap, rect, point); // Draw the current source image into frame 0
+ else b.copyPixels(ghostBitmaps[i - 1], rect, point); // Move the other frames along the array
+ }
+
+ // Blend the final delayed frame with the current source image
+ sourceBitmap.merge(ghostBitmaps[frames - 1], rect, point, 128, 128, 128, 0);
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ }
+
+ /**
+ * Removes the ghost effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the frame bitmaps
+ for (var i:int = frames; i--; )
+ {
+ ghostBitmaps[i].dispose();
+ ghostBitmaps[i] = null;
+ }
+ ghostBitmaps = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/delay/SlitScanEffect.as b/webcam/webcam/effects/delay/SlitScanEffect.as new file mode 100755 index 0000000..37eb00c --- /dev/null +++ b/webcam/webcam/effects/delay/SlitScanEffect.as @@ -0,0 +1,178 @@ +/**
+ * Neave Webcam // Slit Scan Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class SlitScanEffect extends AbstractEffect
+ {
+ private const MAX_SLITS:int = 60;
+
+ private var slitHeight:int;
+ private var slitScale:Number;
+ private var initScale:Number;
+ private var total:int;
+ private var slitBitmaps:Array;
+ private var slitMatrix:Matrix;
+ private var slitRect:Rectangle;
+ private var halfBitmap:BitmapData;
+ private var topMatrix:Matrix;
+ private var bottomPoint:Point;
+ private var moveUp:Boolean;
+ private var midX:Number;
+
+ /**
+ * Creates a slit scan effect, similar to the final scene in 2001: A Space Odyssey
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param slitHeight The height of the slit to capture in pixels
+ * @param slitScale How much to increase the size of each slit by
+ * @param initScale The scale of the first slit
+ */
+ public function SlitScanEffect(source:IBitmapDrawable, targetBitmap:BitmapData, slitHeight:int = 1, slitScale:Number = 1.125, initScale:Number = 0.25)
+ {
+ super(source, targetBitmap, "Slit Scan");
+ this.slitHeight = slitHeight < 1 ? 1 : slitHeight;
+ this.slitScale = slitScale < 0.1 ? 0.1 : slitScale;
+ this.initScale = initScale < 0.1 ? 0.1 : initScale;
+
+ createSlitScan();
+ }
+
+ /**
+ * Sets up the slit scan effect
+ */
+ private function createSlitScan():void
+ {
+ // Slit dimensions
+ slitMatrix = new Matrix();
+ slitRect = new Rectangle(0, 0, rect.width, slitHeight);
+
+ // Create a half-sized bitmap to contain all the slit scans
+ halfBitmap = new BitmapData(rect.width, Math.round(rect.height / 2), false, 0xFF000000);
+ topMatrix = new Matrix(1, 0, 0, -1, 0, halfBitmap.height);
+ bottomPoint = new Point(0, halfBitmap.height);
+
+ // Create an array of bitmaps to store the slits
+ slitBitmaps = new Array();
+ setTotal();
+ for (var i:int = total; i--; )
+ {
+ var b:BitmapData = new BitmapData(rect.width, slitHeight, false, 0xFF000000);
+ b.draw(source, null, color, null, slitRect, true); // Start with the current source image
+ slitBitmaps.push(b);
+ }
+
+ // Other variables
+ moveUp = false;
+ midX = rect.width / 2 / initScale - rect.width / 2;
+ }
+
+ /**
+ * Calculates the total number of slits needed to cover the half-sized bitmap
+ */
+ private function setTotal():void
+ {
+ total = 0;
+ var size:Number = slitHeight * initScale;
+ var lastSize:Number = size;
+
+ // Loop through the slit sizes, increasing in height until the size is bigger than the bitmap height
+ while (size < halfBitmap.height && total < MAX_SLITS)
+ {
+ var nextSize:Number = lastSize * slitScale;
+ lastSize = nextSize;
+ size += nextSize;
+ total++;
+ }
+ }
+
+ /**
+ * Moves the slit position up or down the source image
+ */
+ private function moveSlit():void
+ {
+ if (moveUp)
+ {
+ // Moving up or reversing direction
+ if (slitRect.top > 1) slitRect.offset(0, -slitHeight);
+ else moveUp = false;
+ }
+ else
+ {
+ // Moving down or reversing direction
+ if (slitRect.top < rect.height - slitHeight - 1) slitRect.offset(0, slitHeight);
+ else moveUp = true;
+ }
+ }
+
+ /**
+ * Draw the slit scan effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Move the slit up or down
+ moveSlit();
+
+ // Set slit to initial position and size
+ slitMatrix.identity();
+ slitMatrix.tx = midX;
+ slitMatrix.scale(initScale, initScale);
+
+ // Draw each slit
+ for (var i:int = total; i--; )
+ {
+ // Draw or move each slit along the array
+ var b:BitmapData = slitBitmaps[i];
+ if (i == 0) b.copyPixels(sourceBitmap, slitRect, point); // Draw the current source image into slit 0
+ else b.copyPixels(slitBitmaps[i - 1], b.rect, point); // Move the other slits along the array
+
+ // Scale each slit up and position in the middle
+ slitMatrix.scale(slitScale, slitScale);
+ slitMatrix.translate(rect.width / 2 * (1 - slitScale), slitHeight * initScale);
+
+ // Draw this new slit into the main half-size bitmap
+ halfBitmap.draw(slitBitmaps[total - i - 1], slitMatrix, null, null, null, true);
+ }
+
+ // Draw the half-size bitmaps into the top and bottom
+ targetBitmap.lock();
+ targetBitmap.draw(halfBitmap, topMatrix);
+ targetBitmap.copyPixels(halfBitmap, halfBitmap.rect, bottomPoint);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the slit scan effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the frame bitmaps
+ for (var i:int = total; i--; )
+ {
+ slitBitmaps[i].dispose();
+ slitBitmaps[i] = null;
+ }
+ slitBitmaps = null;
+
+ halfBitmap.dispose();
+ halfBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/delay/TrailEffect.as b/webcam/webcam/effects/delay/TrailEffect.as new file mode 100755 index 0000000..41a9c91 --- /dev/null +++ b/webcam/webcam/effects/delay/TrailEffect.as @@ -0,0 +1,68 @@ +/**
+ * Neave Webcam // Trail Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.delay
+{
+ import flash.display.*;
+ import com.neave.webcam.effects.*;
+
+ public class TrailEffect extends AbstractEffect
+ {
+ private var fade:uint;
+ private var whiteBitmap:BitmapData;
+
+ /**
+ * Creates a trail effect by smearing and fading out movement
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param fade The amount to fade out the trail by each frame, the higher the faster
+ */
+ public function TrailEffect(source:IBitmapDrawable, targetBitmap:BitmapData, fade:uint = 8)
+ {
+ super(source, targetBitmap, "Trail");
+ this.fade = fade > 0xFF ? 0xFF: fade;
+
+ createTrail();
+ }
+
+ /**
+ * Sets up the trail effect
+ */
+ private function createTrail():void
+ {
+ whiteBitmap = new BitmapData(rect.width, rect.height, false, 0xFFFFFFFF); // White bitmap for fading out the trail
+ targetBitmap.draw(source, null, color, null, null, true); // Start with the current source image
+ }
+
+ /**
+ * Draws the trail effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.lock();
+ targetBitmap.merge(whiteBitmap, rect, point, fade, fade, fade, 0); // Repeatedly fade out the image
+ targetBitmap.draw(sourceBitmap, null, null, BlendMode.DARKEN); // Blend the new source image with the old one
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the divide effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ whiteBitmap.dispose();
+ whiteBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/displace/AbstractDisplaceEffect.as b/webcam/webcam/effects/displace/AbstractDisplaceEffect.as new file mode 100755 index 0000000..89458ac --- /dev/null +++ b/webcam/webcam/effects/displace/AbstractDisplaceEffect.as @@ -0,0 +1,64 @@ +/**
+ * Neave Webcam // Abstract Displace Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import com.neave.webcam.effects.*;
+
+ internal class AbstractDisplaceEffect extends AbstractEffect
+ {
+ protected var displace:DisplacementMapFilter;
+
+ /**
+ * An abstract displacement effect class, not to be instantiated
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param name The proper name of the effect
+ */
+ public function AbstractDisplaceEffect(source:IBitmapDrawable, targetBitmap:BitmapData, name:String = "")
+ {
+ super(source, targetBitmap, name);
+
+ createAbstractDisplace();
+ }
+
+ /**
+ * Sets up the displacement effect
+ */
+ private function createAbstractDisplace():void
+ {
+ // Create a displacement map filter with grey bitmap data, using red to distort horizontally, green to distort vertically
+ displace = new DisplacementMapFilter(new BitmapData(rect.width, rect.height, false, 0xFF808080), point, BitmapDataChannel.RED, BitmapDataChannel.GREEN, 0, 0, DisplacementMapFilterMode.CLAMP);
+ }
+
+ /**
+ * Draws the displacement effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.applyFilter(sourceBitmap, rect, point, displace);
+ }
+
+ /**
+ * Removes the displacement effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ displace.mapBitmap.dispose();
+ displace = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/displace/BulgeEffect.as b/webcam/webcam/effects/displace/BulgeEffect.as new file mode 100755 index 0000000..d2c1ac2 --- /dev/null +++ b/webcam/webcam/effects/displace/BulgeEffect.as @@ -0,0 +1,74 @@ +/**
+ * Neave Webcam // Bulge Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class BulgeEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a bulge effect that pushes the centre of the image outwards
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function BulgeEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Bulge");
+
+ createBulge();
+ }
+
+ /**
+ * Sets up the bulge effect
+ */
+ private function createBulge():void
+ {
+ // The size of the bulge, one quarter the size of the source image
+ var w:int = rect.width;
+ var h:int = rect.height;
+ var size:int = Math.round((w + h) / 4);
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size, size);
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ cover.graphics.beginGradientFill(GradientType.RADIAL, [0x808080, 0x808080], [0, 1], [0x00, 0xFF], m);
+ cover.graphics.drawRect(0, 0, size, size);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0xFF0000, 0x000000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, size, size);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.rotate(Math.PI / 2);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x00FF00, 0x000000], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, size, size);
+
+ // Draw all the gradients into one displacement map bitmap
+ var mapMatrix:Matrix = new Matrix();
+ mapMatrix.translate(w / 2 - size / 2, h / 2 - size / 2);
+ displace.mapBitmap.draw(red, mapMatrix);
+ displace.mapBitmap.draw(green, mapMatrix, null, BlendMode.ADD);
+ displace.mapBitmap.draw(cover, mapMatrix);
+
+ // Set the size of the displacement
+ displace.scaleX = displace.scaleY = size;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/displace/DentEffect.as b/webcam/webcam/effects/displace/DentEffect.as new file mode 100755 index 0000000..c701146 --- /dev/null +++ b/webcam/webcam/effects/displace/DentEffect.as @@ -0,0 +1,75 @@ +/**
+ * Neave Webcam // Dent Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class DentEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a dent effect that pinches the centre of the image inwards
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function DentEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Dent");
+
+ createDent();
+ }
+
+ /**
+ * Sets up the dent effect
+ */
+ private function createDent():void
+ {
+ // The size of the dent, one quarter the size of the source image
+ var w:int = rect.width;
+ var h:int = rect.height;
+ var size:int = Math.round((w + h) / 4);
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size, size);
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ cover.graphics.beginGradientFill(GradientType.RADIAL, [0x808080, 0x808080], [0, 1], [0x00, 0xFF], m);
+ cover.graphics.drawRect(0, 0, size, size);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0x000000, 0xFF0000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, size, size);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.rotate(Math.PI / 2);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x000000, 0x00FF00], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, size, size);
+
+ // Draw all the gradients into one displacement map bitmap
+ var mapMatrix:Matrix = new Matrix();
+ mapMatrix.translate(w / 2 - size / 2, h / 2 - size / 2);
+ displace.mapBitmap.draw(red, mapMatrix);
+ displace.mapBitmap.draw(green, mapMatrix, null, BlendMode.ADD);
+ displace.mapBitmap.draw(cover, mapMatrix);
+
+ // Double up the grey cover for a greater dent size
+ displace.mapBitmap.draw(cover, mapMatrix);
+ displace.scaleX = displace.scaleY = size * 2;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/displace/FishbowlEffect.as b/webcam/webcam/effects/displace/FishbowlEffect.as new file mode 100755 index 0000000..08f5d08 --- /dev/null +++ b/webcam/webcam/effects/displace/FishbowlEffect.as @@ -0,0 +1,72 @@ +/**
+ * Neave Webcam // Fishbowl Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class FishbowlEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a fishbowl effect like looking into a fishbowl, the opposite of the fisheye effect
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function FishbowlEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Fishbowl");
+
+ createFishbowl();
+ }
+
+ /**
+ * Sets up the fishbowl effect
+ */
+ private function createFishbowl():void
+ {
+ // The size of the fishbowl effect
+ var w:int = rect.width;
+ var h:int = rect.height;
+ var size:int = Math.round(Math.sqrt((w / 2) * (w / 2) + (h / 2) * (h / 2)) * 2);
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size, size, 0, w / 2 - size / 2, h / 2 - size / 2);
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ cover.graphics.beginGradientFill(GradientType.RADIAL, [0x808080, 0x808080], [1, 0], [0x00, 0xFF], m);
+ cover.graphics.drawRect(0, 0, w, h);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0xFF0000, 0x000000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, w, h);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.rotate(Math.PI / 2);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x00FF00, 0x000000], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, w, h);
+
+ // Draw all the gradients into one displacement map bitmap
+ displace.mapBitmap.draw(red);
+ displace.mapBitmap.draw(green, null, null, BlendMode.ADD);
+ displace.mapBitmap.draw(cover);
+
+ // Set the size of the displacement
+ displace.scaleX = displace.scaleY = size;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/displace/FisheyeEffect.as b/webcam/webcam/effects/displace/FisheyeEffect.as new file mode 100755 index 0000000..1d4cf4a --- /dev/null +++ b/webcam/webcam/effects/displace/FisheyeEffect.as @@ -0,0 +1,72 @@ +/**
+ * Neave Webcam // Fisheye Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class FisheyeEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a fisheye (wide-angle) lens effect
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function FisheyeEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Fisheye");
+
+ createFisheye();
+ }
+
+ /**
+ * Sets up the fisheye effect
+ */
+ private function createFisheye():void
+ {
+ // The size of the fisheye effect
+ var w:int = rect.width;
+ var h:int = rect.height;
+ var size:int = (w + h) / 2;
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size, size, 0, w / 2 - size / 2, h / 2 - size / 2);
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ cover.graphics.beginGradientFill(GradientType.RADIAL, [0x808080, 0x808080], [0, 1], [0x00, 0xFF], m, SpreadMethod.REFLECT);
+ cover.graphics.drawRect(0, 0, w, h);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0xFF0000, 0x000000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, w, h);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.rotate(Math.PI / 2);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x00FF00, 0x000000], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, w, h);
+
+ // Draw all the gradients into one displacement map bitmap
+ displace.mapBitmap.draw(red);
+ displace.mapBitmap.draw(green, null, null, BlendMode.ADD);
+ displace.mapBitmap.draw(cover);
+
+ // Set the size of the displacement
+ displace.scaleX = displace.scaleY = size;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/displace/FragmentEffect.as b/webcam/webcam/effects/displace/FragmentEffect.as new file mode 100755 index 0000000..e058dd9 --- /dev/null +++ b/webcam/webcam/effects/displace/FragmentEffect.as @@ -0,0 +1,101 @@ +/**
+ * Neave Webcam // Fragment Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class FragmentEffect extends AbstractEffect
+ {
+ private var fragmentsWide:int;
+ private var scale:Number;
+ private var total:int;
+ private var fragmentBitmap:BitmapData;
+ private var fragmentMatrix:Matrix;
+ private var fragmentRects:Array;
+ private var fragmentPoints:Array;
+
+ /**
+ * Creates a fragmentary effect where the image is divided into a grid of smaller zoomed areas
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param fragmentsWide The number of fragments in width to use
+ * @param scale The size of the zoom for each fragment
+ */
+ public function FragmentEffect(source:IBitmapDrawable, targetBitmap:BitmapData, fragmentsWide:int = 10, scale:Number = 0.5)
+ {
+ super(source, targetBitmap, "Fragment");
+ this.fragmentsWide = fragmentsWide < 1 ? 1 : fragmentsWide;
+ this.scale = scale;
+ if (scale > 2) this.scale = 2;
+ if (scale < 0.5) this.scale = 0.5;
+
+ createFragment();
+ }
+
+ /**
+ * Sets up the fragment effect
+ */
+ private function createFragment():void
+ {
+ // The fragment dimensions
+ var w:Number = rect.width / fragmentsWide;
+ var h:Number = rect.height / fragmentsWide;
+
+ // Set up the main fragment bitmap data and scaling properties
+ fragmentBitmap = new BitmapData(rect.width * scale, rect.height * scale, false, 0xFF000000);
+ fragmentMatrix = new Matrix();
+ fragmentMatrix.scale(1 / scale, 1 / scale);
+ fragmentRects = new Array();
+ fragmentPoints = new Array();
+
+ // Set up each fragment's area and position
+ for (var y:int = 0; y < fragmentsWide; y++)
+ {
+ for (var x:int = 0; x < fragmentsWide; x++)
+ {
+ fragmentRects.push(new Rectangle(x * w, y * h, w * scale, h * scale));
+ fragmentPoints.push(new Point(x * w * scale, y * h * scale));
+ }
+ }
+ total = fragmentsWide * fragmentsWide;
+ }
+
+ /**
+ * Draws the fragment effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through each fragment and draw the zoomed area
+ for (var i:int = total; i--; ) fragmentBitmap.copyPixels(sourceBitmap, fragmentRects[i], fragmentPoints[i]);
+
+ // Draw the fragment bitmap data into the target bitmap data but scaled to fit
+ targetBitmap.draw(fragmentBitmap, fragmentMatrix, null, null, null, true);
+ }
+
+ /**
+ * Removes the fragment effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ fragmentBitmap.dispose();
+ fragmentBitmap = null;
+ fragmentRects = null;
+ fragmentPoints = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/displace/SqueezeEffect.as b/webcam/webcam/effects/displace/SqueezeEffect.as new file mode 100755 index 0000000..e702dc1 --- /dev/null +++ b/webcam/webcam/effects/displace/SqueezeEffect.as @@ -0,0 +1,87 @@ +/**
+ * Neave Webcam // Squeeze Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class SqueezeEffect extends AbstractDisplaceEffect
+ {
+ /**
+ * Creates a squeezing distortion effect where the middle is squeezed and the edges are stretched
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function SqueezeEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Squeeze");
+
+ createSqueeze();
+ }
+
+ /**
+ * Sets up the squeeze effect
+ */
+ private function createSqueeze():void
+ {
+ // The size of the squeeze effect
+ var w:int = rect.width;
+ var h:int = rect.height;
+
+ // The displacement gradient matrix
+ var m:Matrix = new Matrix();
+
+ // Grey radial gradient to smooth the edges of the distortion
+ var cover:Shape = new Shape();
+ m.createGradientBox(w, w);
+ cover.graphics.beginGradientFill(GradientType.LINEAR, [0x808080, 0x808080], [1, 0], [0x00, 0xFF], m);
+ cover.graphics.drawRect(0, 0, w, w);
+
+ // Red gradient to distort pixels horizontally
+ var red:Shape = new Shape();
+ m.createGradientBox(h, h, 0, (w - h) / 2, 0);
+ red.graphics.beginGradientFill(GradientType.LINEAR, [0x000000, 0xFF0000], [1, 1], [0x00, 0xFF], m);
+ red.graphics.drawRect(0, 0, w, w);
+
+ // Green gradient to distort pixels vertically
+ var green:Shape = new Shape();
+ m.createGradientBox(h, h, Math.PI / 2, (w - h) / 2, 0);
+ green.graphics.beginGradientFill(GradientType.LINEAR, [0x000000, 0x00FF00], [1, 1], [0x00, 0xFF], m);
+ green.graphics.drawRect(0, 0, w, w);
+
+ // Draw red and green gradients into one displacement map bitmap
+ displace.mapBitmap.draw(red);
+ displace.mapBitmap.draw(green, null, null, BlendMode.ADD);
+
+ // Fade out the edges of the distorion linearly in each direction, up, down, left and right
+ m.identity();
+ m.scale(0.5, 1);
+ displace.mapBitmap.draw(cover, m);
+ m.rotate(Math.PI);
+ m.translate(w, h);
+ displace.mapBitmap.draw(cover, m);
+ m.identity();
+ m.scale(h / w / 2, 1);
+ m.rotate(Math.PI / 2);
+ m.translate(w, 0);
+ displace.mapBitmap.draw(cover, m);
+ m.rotate(Math.PI);
+ m.translate(w, h);
+ displace.mapBitmap.draw(cover, m);
+
+ // Set the size of the displacement
+ displace.scaleX = displace.scaleY = w;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/displace/WaterEffect.as b/webcam/webcam/effects/displace/WaterEffect.as new file mode 100755 index 0000000..4f45d72 --- /dev/null +++ b/webcam/webcam/effects/displace/WaterEffect.as @@ -0,0 +1,76 @@ +/**
+ * Neave Webcam // Water Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.displace
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class WaterEffect extends AbstractDisplaceEffect
+ {
+ private var seed:int;
+ private var offsets:Array;
+ private var blue:ColorMatrixFilter;
+
+ /**
+ * Creates a water effect as if you were looking into a pool of waving water
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function WaterEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Water");
+
+ createWater();
+ }
+
+ /**
+ * Sets up the water effect
+ */
+ private function createWater():void
+ {
+ // Set up the displacement
+ displace.scaleX = rect.width * 0.25;
+ displace.scaleY = rect.height * 0.25;
+ seed = Math.floor(Math.random() * 256);
+ offsets = new Array(new Point(), new Point());
+
+ // Blue colour matrix
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, -10]); // Red
+ m = m.concat([0.3, 0.59, 0.11, 0, 30]); // Green
+ m = m.concat([0.3, 0.59, 0.11, 0, 70]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ blue = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the water effect
+ */
+ override public function draw():void
+ {
+ // Wave the water by moving the displacement map's offsets
+ offsets[0].x += rect.width * 0.06;
+ offsets[1].x += rect.height * 0.06;
+
+ // Generate perlin noise as a displacement map to make water waves
+ displace.mapBitmap.perlinNoise(rect.width * 0.5, rect.height * 0.5, 1, seed, false, true, BitmapDataChannel.RED | BitmapDataChannel.GREEN, false, offsets);
+
+ // Draw the displaced image and tint it blue
+ targetBitmap.lock();
+ super.draw();
+ targetBitmap.applyFilter(targetBitmap, rect, point, blue);
+ targetBitmap.unlock();
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/mirror/AbstractMirrorEffect.as b/webcam/webcam/effects/mirror/AbstractMirrorEffect.as new file mode 100755 index 0000000..57008f7 --- /dev/null +++ b/webcam/webcam/effects/mirror/AbstractMirrorEffect.as @@ -0,0 +1,68 @@ +/**
+ * Neave Webcam // Abstract Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ internal class AbstractMirrorEffect extends AbstractEffect
+ {
+ protected var mirrorBitmap:BitmapData;
+ protected var mirrorMatrix:Matrix;
+ protected var mirrorPoint:Point;
+
+ /**
+ * An abstract mirror effect class, not to be instantiated
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param name The proper name of the effect
+ */
+ public function AbstractMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData, name:String = "")
+ {
+ super(source, targetBitmap, name);
+
+ createAbstractMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createAbstractMirror():void
+ {
+ mirrorMatrix = new Matrix();
+ mirrorPoint = new Point();
+ }
+
+ /**
+ * Draws the mirror effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ mirrorBitmap.draw(sourceBitmap, mirrorMatrix);
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ targetBitmap.copyPixels(mirrorBitmap, rect, mirrorPoint);
+ }
+
+ /**
+ * Removes the mirror effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ mirrorBitmap.dispose();
+ mirrorBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/mirror/BottomMirrorEffect.as b/webcam/webcam/effects/mirror/BottomMirrorEffect.as new file mode 100755 index 0000000..4bb7b07 --- /dev/null +++ b/webcam/webcam/effects/mirror/BottomMirrorEffect.as @@ -0,0 +1,41 @@ +/**
+ * Neave Webcam // Bottom Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class BottomMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the bottom half of the image is reflected into the top half
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function BottomMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Bottom Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ mirrorMatrix.scale(1, -1);
+ mirrorMatrix.translate(0, rect.height);
+ mirrorBitmap = new BitmapData(rect.width, Math.round(rect.height / 2), false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/mirror/InverseMirrorEffect.as b/webcam/webcam/effects/mirror/InverseMirrorEffect.as new file mode 100755 index 0000000..8f0da4c --- /dev/null +++ b/webcam/webcam/effects/mirror/InverseMirrorEffect.as @@ -0,0 +1,41 @@ +/**
+ * Neave Webcam // Inverse Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class InverseMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the top half of the image is inversed
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function InverseMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Inverse Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ mirrorMatrix.scale(-1, 1);
+ mirrorMatrix.translate(rect.width, 0);
+ mirrorBitmap = new BitmapData(rect.width, Math.round(rect.height / 2), false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/mirror/LeftMirrorEffect.as b/webcam/webcam/effects/mirror/LeftMirrorEffect.as new file mode 100755 index 0000000..31cc510 --- /dev/null +++ b/webcam/webcam/effects/mirror/LeftMirrorEffect.as @@ -0,0 +1,41 @@ +/**
+ * Neave Webcam // Left Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class LeftMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the left side of the image is reflected into the right side (when using a flipped image)
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function LeftMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Left Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ mirrorMatrix.scale(-1, 1);
+ mirrorMatrix.translate(rect.width, 0);
+ mirrorBitmap = new BitmapData(Math.round(rect.width / 2), rect.height, false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/mirror/QuadMirrorEffect.as b/webcam/webcam/effects/mirror/QuadMirrorEffect.as new file mode 100755 index 0000000..d4e84a4 --- /dev/null +++ b/webcam/webcam/effects/mirror/QuadMirrorEffect.as @@ -0,0 +1,97 @@ +/**
+ * Neave Webcam // Quad Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class QuadMirrorEffect extends AbstractEffect
+ {
+ private var quadBitmap:BitmapData;
+ private var halfBitmap:BitmapData;
+ private var quadMatrix:Matrix;
+ private var rightMatrix:Matrix;
+ private var topMatrix:Matrix;
+ private var bottomMatrix:Matrix;
+
+ /**
+ * Creates a mirror effect where the source image is reflected vertically and horizontally
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function QuadMirrorEffect(source:IBitmapDrawable, targetBitmapData:BitmapData)
+ {
+ super(source, targetBitmapData, "Quad Mirror");
+
+ createQuadMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createQuadMirror():void
+ {
+ // Mirror dimensions
+ var midW:int = Math.round(rect.width / 2);
+ var midH:int = Math.round(rect.height / 2);
+
+ // Reflected bitmap data
+ quadBitmap = new BitmapData(midW, midH, false, 0xFF000000);
+ halfBitmap = new BitmapData(rect.width, midH, false, 0xFF000000);
+
+ // Half size matrix
+ quadMatrix = new Matrix();
+ quadMatrix.scale(0.5, 0.5);
+
+ // Right side matrix
+ rightMatrix = new Matrix();
+ rightMatrix.scale(-1, 1);
+ rightMatrix.translate(rect.width, 0);
+
+ // Top half matrix
+ topMatrix = new Matrix();
+ topMatrix.scale(1, -1);
+ topMatrix.translate(0, midH);
+
+ // Bottom half matrix
+ bottomMatrix = new Matrix();
+ bottomMatrix.translate(0, midH);
+ }
+
+ /**
+ * Draws the quad mirror effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ quadBitmap.draw(sourceBitmap, quadMatrix); // Draw quarter image
+ halfBitmap.draw(quadBitmap); // Draw quarter into left
+ halfBitmap.draw(quadBitmap, rightMatrix); // Draw quarter into right
+ targetBitmap.draw(halfBitmap, bottomMatrix); // Draw half into bottom
+ targetBitmap.draw(halfBitmap, topMatrix); // Draw half into top
+ }
+
+ /**
+ * Removes the quad mirror effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ quadBitmap.dispose();
+ quadBitmap = null;
+ halfBitmap.dispose();
+ halfBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/mirror/RightMirrorEffect.as b/webcam/webcam/effects/mirror/RightMirrorEffect.as new file mode 100755 index 0000000..d469226 --- /dev/null +++ b/webcam/webcam/effects/mirror/RightMirrorEffect.as @@ -0,0 +1,44 @@ +/**
+ * Neave Webcam // Right Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class RightMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the right side of the image is reflected into the left side (when using a flipped image)
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function RightMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Right Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ var midW:int = Math.round(rect.width / 2);
+
+ mirrorMatrix.scale(-1, 1);
+ mirrorMatrix.translate(midW, 0);
+ mirrorPoint.x = midW;
+ mirrorBitmap = new BitmapData(midW, rect.height, false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/mirror/TopMirrorEffect.as b/webcam/webcam/effects/mirror/TopMirrorEffect.as new file mode 100755 index 0000000..af69612 --- /dev/null +++ b/webcam/webcam/effects/mirror/TopMirrorEffect.as @@ -0,0 +1,44 @@ +/**
+ * Neave Webcam // Top Mirror Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+
+ public class TopMirrorEffect extends AbstractMirrorEffect
+ {
+ /**
+ * Creates a mirror effect where the top half of the image is reflected into the bottom half
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function TopMirrorEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Top Mirror");
+
+ createMirror();
+ }
+
+ /**
+ * Sets up the mirror effect
+ */
+ private function createMirror():void
+ {
+ var midH:int = Math.round(rect.height / 2);
+
+ mirrorMatrix.scale(1, -1);
+ mirrorMatrix.translate(0, midH);
+ mirrorPoint.y = midH;
+ mirrorBitmap = new BitmapData(rect.width, midH, false, 0xFF000000);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/mirror/UpsideDownEffect.as b/webcam/webcam/effects/mirror/UpsideDownEffect.as new file mode 100755 index 0000000..71e08d8 --- /dev/null +++ b/webcam/webcam/effects/mirror/UpsideDownEffect.as @@ -0,0 +1,54 @@ +/**
+ * Neave Webcam // Upside-Down Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.mirror
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class UpsideDownEffect extends AbstractEffect
+ {
+ private var flipMatrix:Matrix;
+
+ /**
+ * Creates a mirror effect where the source image is flipped vertically
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function UpsideDownEffect(source:IBitmapDrawable, targetBitmapData:BitmapData)
+ {
+ super(source, targetBitmapData, "Upside-Down");
+
+ createUpsideDown();
+ }
+
+ /**
+ * Sets up the upside-down effect
+ */
+ private function createUpsideDown():void
+ {
+ flipMatrix = new Matrix();
+ flipMatrix.scale(1, -1);
+ flipMatrix.translate(0, rect.height);
+ }
+
+ /**
+ * Draws the upside-down effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ targetBitmap.draw(sourceBitmap, flipMatrix);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/motion/AbstractMotionEffect.as b/webcam/webcam/effects/motion/AbstractMotionEffect.as new file mode 100755 index 0000000..3301a8a --- /dev/null +++ b/webcam/webcam/effects/motion/AbstractMotionEffect.as @@ -0,0 +1,138 @@ +/**
+ * Neave Webcam // Abstract Motion Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ internal class AbstractMotionEffect extends AbstractEffect
+ {
+ private var motionScale:int;
+ private var motionFrames:int;
+ private var contrast:ColorTransform;
+ private var frames:Array;
+ private var frameBitmap:BitmapData;
+ protected var monochrome:ColorMatrixFilter;
+ protected var motionBitmap:BitmapData;
+ protected var motionRect:Rectangle;
+ protected var motionMatrix:Matrix;
+
+ /**
+ * An abstract motion detection effect class, not to be instantiated
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param name The proper name of the effect
+ * @param motionScale The scale of the motion bitmap data to use for detection
+ * @param motionFrames The number of frames to capture for the motion bitmap data
+ */
+ public function AbstractMotionEffect(source:IBitmapDrawable, targetBitmap:BitmapData, name:String = "", motionScale:int = 1, motionFrames:int = 4)
+ {
+ super(source, targetBitmap, name);
+ this.motionScale = motionScale < 1 ? 1 : motionScale;
+ this.motionFrames = motionFrames < 1 ? 1 : motionFrames;
+
+ createAbstractMotion();
+ }
+
+ /**
+ * Sets up the motion effect
+ */
+ private function createAbstractMotion():void
+ {
+ // Increase contrast
+ contrast = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Motion bitmap dimensions
+ var w:int = Math.round(rect.width / motionScale);
+ var h:int = Math.round(rect.height / motionScale);
+
+ // Main motion bitmap data
+ motionBitmap = new BitmapData(w, h, false, 0xFF000000);
+ motionRect = motionBitmap.rect;
+ motionMatrix = new Matrix();
+ motionMatrix.scale(1 / motionScale, 1 / motionScale);
+
+ // The previous frame to use when comparing with the current image
+ frameBitmap = motionBitmap.clone();
+ frameBitmap.draw(source, motionMatrix, contrast);
+
+ // Create the delayed motion frames
+ frames = new Array();
+ for (var i:int = motionFrames; i--; ) frames.push(new BitmapData(w, h, false, 0xFF000000));
+
+ // Monochrome colour matrix
+ var m:Array = new Array();
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Red
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Green
+ m = m.concat([0.3, 0.59, 0.11, 0, 0]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ monochrome = new ColorMatrixFilter(m);
+ }
+
+ /**
+ * Draws the motion effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Clear old motion bitmap
+ motionBitmap.fillRect(motionRect, 0xFF000000);
+
+ // Do motion detection
+ for (var i:int = motionFrames; i--; )
+ {
+ var b:BitmapData = frames[i];
+ if (i == 0)
+ {
+ // Detect motion by taking the difference between this source image to the previous source image
+ b.copyPixels(frameBitmap, motionRect, point); // Get the old image
+ frameBitmap.draw(sourceBitmap, motionMatrix, contrast); // Draw the new image
+ frameBitmap.applyFilter(frameBitmap, motionRect, point, monochrome); // Convert the new image to greyscale
+ b.draw(frameBitmap, null, null, BlendMode.DIFFERENCE); // Draw the difference
+ }
+ else b.copyPixels(frames[i - 1], motionRect, point); // Move the motion frames along the array
+
+ // Add all the motion frames into a single bitmap
+ motionBitmap.draw(b, null, null, BlendMode.ADD);
+ }
+
+ // Separate the motion bitmap data into only black and white pixels
+ motionBitmap.threshold(motionBitmap, motionRect, point, ">", 0xFF808080, 0xFFFFFFFF);
+ motionBitmap.threshold(motionBitmap, motionRect, point, "<=", 0xFF808080, 0xFF000000);
+ }
+
+ /**
+ * Removes the motion effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the motion frames
+ for (var i:int = motionFrames; i--; )
+ {
+ frames[i].dispose();
+ frames[i] = null;
+ }
+ frames = null;
+
+ frameBitmap.dispose();
+ frameBitmap = null;
+ motionBitmap.dispose();
+ motionBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/motion/FireEffect.as b/webcam/webcam/effects/motion/FireEffect.as new file mode 100755 index 0000000..33dcfe2 --- /dev/null +++ b/webcam/webcam/effects/motion/FireEffect.as @@ -0,0 +1,129 @@ +/**
+ * Neave Webcam // Fire Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+
+ public class FireEffect extends AbstractMotionEffect
+ {
+ private const MOTION_SCALE:int = 2;
+
+ private var fireSourceBitmap:BitmapData;
+ private var fireBitmap:BitmapData;
+ private var darkenBitmap:BitmapData;
+ private var edge:ConvolutionFilter;
+ private var fireColor:ColorMatrixFilter;
+ private var displace:DisplacementMapFilter;
+ private var blur:BlurFilter;
+ private var targetMatrix:Matrix;
+
+ /**
+ * Creates a fire effect which animates along edges and as motion is detected
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function FireEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Fire", MOTION_SCALE, 5);
+
+ createFire();
+ }
+
+ /**
+ * Sets up the fire effect
+ */
+ private function createFire():void
+ {
+ // Set up fire bitmap data and scaling
+ fireSourceBitmap = motionBitmap.clone();
+ fireBitmap = motionBitmap.clone();
+ targetMatrix = new Matrix();
+ targetMatrix.scale(MOTION_SCALE, MOTION_SCALE);
+
+ // Edge detection convolution array
+ var m:Array =
+ [
+ 0, 0, 0,
+ 16, 16, 16,
+ -16, -16, -16
+ ];
+ edge = new ConvolutionFilter(3, 3, m, 9);
+
+ // Fire colour matrix
+ m = new Array();
+ m = m.concat([0.8, 0.05, 0, 0, 0]); // Red
+ m = m.concat([0, 0.65, 0, 0, 0]); // Green
+ m = m.concat([0, 0, 0.5, 0, 0]); // Blue
+ m = m.concat([0, 0, 0, 1, 0]); // Alpha
+ fireColor = new ColorMatrixFilter(m);
+
+ // Fire displacement map
+ displace = new DisplacementMapFilter(new BitmapData(rect.width, rect.height, false, 0xFF808080), point, BitmapDataChannel.RED, BitmapDataChannel.GREEN, 7, -35, DisplacementMapFilterMode.CLAMP);
+
+ // Fire blurring
+ blur = new BlurFilter(8, 8, 1);
+
+ // Darken the fire
+ darkenBitmap = new BitmapData(rect.width, rect.height, false, 0xFFFF8000);
+ }
+
+ /**
+ * Draws the fire effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Get the source image's edges
+ fireSourceBitmap.draw(sourceBitmap, motionMatrix);
+ fireBitmap.applyFilter(fireSourceBitmap, motionRect, point, edge);
+ fireBitmap.applyFilter(fireBitmap, motionRect, point, monochrome);
+
+ // Add motion bitmap to edge bitmap and turn pixels into orange and black only
+ fireBitmap.draw(motionBitmap, null, null, BlendMode.ADD);
+ fireBitmap.threshold(fireBitmap, motionRect, point, ">", 0xFF808080, 0xFFFF8000);
+ fireBitmap.threshold(fireBitmap, motionRect, point, "<=", 0xFF808080, 0xFF000000);
+
+ // Blur to make motion bitmap look more like fire
+ fireBitmap.applyFilter(fireBitmap, motionRect, point, blur);
+
+ // Displace the image with perlin noise to animate the fire
+ displace.mapBitmap.perlinNoise(14, 10, 1, Math.floor(Math.random() * 256), false, true, BitmapDataChannel.RED | BitmapDataChannel.GREEN, false);
+ displace.mapBitmap.draw(darkenBitmap, null, null, BlendMode.DARKEN);
+ fireBitmap.applyFilter(fireBitmap, motionRect, point, displace);
+ fireBitmap.applyFilter(fireBitmap, motionRect, point, fireColor);
+
+ // Draw the fire bitmap on top of the current source image
+ targetBitmap.lock();
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ targetBitmap.draw(fireBitmap, targetMatrix, null, BlendMode.ADD);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the fire effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ fireSourceBitmap.dispose();
+ fireSourceBitmap = null;
+ fireBitmap.dispose();
+ fireBitmap = null;
+ darkenBitmap.dispose();
+ darkenBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/motion/SnowEffect.as b/webcam/webcam/effects/motion/SnowEffect.as new file mode 100755 index 0000000..30468d9 --- /dev/null +++ b/webcam/webcam/effects/motion/SnowEffect.as @@ -0,0 +1,154 @@ +/**
+ * Neave Webcam // Snow Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.events.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import flash.utils.*;
+ import com.neave.webcam.effects.*;
+
+ public class SnowEffect extends AbstractEffect
+ {
+ private const SNOWFLAKE_DELAY:int = 20;
+ private const MELT_SPEED:Number = 0.0025;
+
+ private var totalFlakes:int;
+ private var snowSourceBitmap:BitmapData;
+ private var edgeBitmap:BitmapData;
+ private var edge:ConvolutionFilter;
+ private var blur:BlurFilter;
+ private var snowflakes:Sprite;
+ private var snowTimer:Timer;
+ private var snowMatrix:Matrix;
+ private var contrast:ColorTransform;
+
+ /**
+ * Creates a snow effect where falling snowflakes settle and build up along edges
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param totalFlakes The total number of snowflakes to use
+ */
+ public function SnowEffect(source:IBitmapDrawable, targetBitmap:BitmapData, totalFlakes:int = 200)
+ {
+ super(source, targetBitmap, "Snow");
+ this.totalFlakes = totalFlakes < 1 ? 1 : totalFlakes;
+
+ createSnow();
+ }
+
+ /**
+ * Sets up the snow effect
+ */
+ private function createSnow():void
+ {
+ // Increase contrast to better detect edges
+ //contrast = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Create bitmaps to hold edge detection
+ snowSourceBitmap = new BitmapData(Math.round(rect.width / 2), Math.round(rect.height / 2), false, 0xFF000000);
+ edgeBitmap = snowSourceBitmap.clone();
+ snowMatrix = new Matrix();
+ snowMatrix.scale(0.5, 0.5);
+
+ // Add a new snowflake to the snowflakes sprite every so often
+ snowflakes = new Sprite();
+ snowTimer = new Timer(SNOWFLAKE_DELAY);
+ snowTimer.addEventListener(TimerEvent.TIMER, makeNewSnowflake);
+ snowTimer.start();
+
+ // Edge detection convolution array
+ var m:Array =
+ [
+ 0, 50, 0,
+ 0, -60, 0,
+ 0, 10, 0
+ ];
+ edge = new ConvolutionFilter(3, 3, m, 5);
+ }
+
+ /**
+ * Creates a new snowflake inside the snowflakes sprite
+ */
+ private function makeNewSnowflake(e:TimerEvent = null):void
+ {
+ // Only add another random snowflake if the maximum amount has not been reached
+ if (snowflakes.numChildren < totalFlakes) snowflakes.addChild(new Snowflake(Math.random() * rect.width, -4, Math.random() * 2 + 1, Math.random() * 2 - 1));
+ }
+
+ /**
+ * Draws the snow effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through each snowflake
+ for (var i:int = snowflakes.numChildren; i--; )
+ {
+ var flake:Snowflake = snowflakes.getChildAt(i) as Snowflake;
+
+ // Only move the snowflake if it is not hitting an edge
+ if (edgeBitmap.getPixel(Math.round(flake.x / 2), Math.round(flake.y / 2)) == 0x000000)
+ {
+ // Animate the snowflake
+ flake.fall();
+ flake.alpha += 0.1;
+ if (flake.alpha > 1) flake.alpha = 1;
+
+ // Wrap the snowflake to within the bounds of the image
+ if (flake.x > rect.width + flake.width) flake.x -= rect.width + flake.width;
+ if (flake.x < -flake.width) flake.x += rect.width + flake.width;
+
+ // Remove this snowflake if it has fallen off the bottom of the image
+ if (flake.y > rect.height + flake.height) snowflakes.removeChildAt(i);
+ }
+ else
+ {
+ // Melt this snowflake by fading out it
+ if (flake.alpha > 0.1) flake.alpha -= MELT_SPEED;
+ else snowflakes.removeChildAt(i);
+ }
+ }
+
+ // Find the edges for the snow to settle on
+ snowSourceBitmap.draw(sourceBitmap, snowMatrix, contrast);
+ edgeBitmap.applyFilter(snowSourceBitmap, edgeBitmap.rect, point, edge);
+ edgeBitmap.threshold(edgeBitmap, edgeBitmap.rect, point, "<", 0xFF808080, 0xFF000000);
+
+ // Draw the snow over the current source image
+ targetBitmap.lock();
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ targetBitmap.draw(snowflakes);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the snow effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Stop making new snowflakes
+ snowTimer.removeEventListener(TimerEvent.TIMER, makeNewSnowflake);
+
+ // Remove bitmap data
+ snowSourceBitmap.dispose();
+ snowSourceBitmap = null;
+ edgeBitmap.dispose();
+ edgeBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/motion/Snowflake.as b/webcam/webcam/effects/motion/Snowflake.as new file mode 100755 index 0000000..fc943f5 --- /dev/null +++ b/webcam/webcam/effects/motion/Snowflake.as @@ -0,0 +1,66 @@ +/**
+ * Neave Webcam // Snowflake
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.geom.*;
+
+ final internal class Snowflake extends Shape
+ {
+ private const SIDEWAYS_DAMPEN:Number = 0.995;
+
+ private var size:Number;
+ private var vx:Number;
+
+ /**
+ * Draws a snowflake shape to be used with the snow effect
+ *
+ * @param x The position of the snowflake on the x-axis
+ * @param y The position of the snowflake on the y-axis
+ * @param size The size of the snowflake
+ * @param vx The sideways velocity of the snowflake
+ */
+ public function Snowflake(x:Number = 0, y:Number = 0, size:Number = 1, vx:Number = 0)
+ {
+ this.x = x;
+ this.y = y;
+ this.size = size;
+ this.vx = vx;
+
+ createSnowflake();
+ }
+
+ /**
+ * Sets up the snowflake shape, a white oval gradient
+ */
+ private function createSnowflake():void
+ {
+ var m:Matrix = new Matrix();
+ m.createGradientBox(size * 2, size * 2);
+ m.translate(-size, -size);
+ graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0xFFFFFF], [1, 0], [0x66, 0xFF], m);
+ graphics.drawCircle(0, 0, size);
+ width *= 1.5;
+ cacheAsBitmap = true;
+ }
+
+ /**
+ * Animates the snowflake downwards
+ */
+ internal function fall():void
+ {
+ vx *= SIDEWAYS_DAMPEN;
+ x += vx;
+ y += size;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/motion/SteamEffect.as b/webcam/webcam/effects/motion/SteamEffect.as new file mode 100755 index 0000000..0b55ca2 --- /dev/null +++ b/webcam/webcam/effects/motion/SteamEffect.as @@ -0,0 +1,73 @@ +/**
+ * Neave Webcam // Steamy Window Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+
+ public class SteamEffect extends AbstractMotionEffect
+ {
+ private var steamBitmap:BitmapData;
+ private var blackBitmap:BitmapData;
+ private var wipedBitmap:BitmapData;
+
+ /**
+ * Creates a steamy window effect where detected motion wipes away areas of the steamed-up image
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ */
+ public function SteamEffect(source:IBitmapDrawable, targetBitmap:BitmapData)
+ {
+ super(source, targetBitmap, "Steamy Window");
+
+ createSteam();
+ }
+
+ /**
+ * Sets up the steam effect
+ */
+ private function createSteam():void
+ {
+ steamBitmap = new BitmapData(rect.width, rect.height, false, 0xFF808080);
+ blackBitmap = new BitmapData(rect.width, rect.height, false, 0xFF000000);
+ wipedBitmap = blackBitmap.clone();
+ }
+
+ /**
+ * Draws the steam effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+ wipedBitmap.draw(motionBitmap, null, null, BlendMode.ADD); // Build up a wiped area by repeatedly adding the motion bitmap
+ wipedBitmap.merge(blackBitmap, rect, point, 2, 2, 2, 0); // Gradually fade away the wiped areas
+ steamBitmap.fillRect(rect, 0xFF808080); // Create some steam
+ steamBitmap.draw(wipedBitmap, null, null, BlendMode.SUBTRACT); // Remove the wiped areas from the steam
+ sourceBitmap.merge(steamBitmap, rect, point, 0x80, 0x80, 0x80, 0); // Merge the steam with the source image
+ targetBitmap.copyPixels(sourceBitmap, rect, point); // Draw into the target bitmap
+ }
+
+ /**
+ * Removes the steam effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ steamBitmap.dispose();
+ steamBitmap = null;
+ blackBitmap.dispose();
+ blackBitmap = null;
+ wipedBitmap.dispose();
+ wipedBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/motion/SwarmEffect.as b/webcam/webcam/effects/motion/SwarmEffect.as new file mode 100755 index 0000000..f22a6bd --- /dev/null +++ b/webcam/webcam/effects/motion/SwarmEffect.as @@ -0,0 +1,106 @@ +/**
+ * Neave Webcam // Swarm Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.geom.*;
+
+ public class SwarmEffect extends AbstractMotionEffect
+ {
+ private const MOTION_SCALE:int = 4;
+
+ private var flies:int;
+ private var swarm:Sprite;
+
+ /**
+ * Creates a swarming flies effect where the flies are attracted to detected motion
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param flies The number of flies to use in the swarm
+ */
+ public function SwarmEffect(source:IBitmapDrawable, targetBitmap:BitmapData, flies:int = 150)
+ {
+ super(source, targetBitmap, "Swarm", MOTION_SCALE);
+ this.flies = flies < 1 ? 1 : flies;
+
+ createSwarm();
+ }
+
+ /**
+ * Sets up the swarm effect
+ */
+ private function createSwarm():void
+ {
+ // Draw the flies into the swarm sprite in random positions
+ swarm = new Sprite();
+ for (var i:int = flies; i--; ) swarm.addChild(new SwarmFly(Math.random() * rect.width, Math.random() * rect.height, (i / flies) * 0.75 + 0.75));
+ }
+
+ /**
+ * Draws the swarm effect
+ */
+ override public function draw():void
+ {
+ super.draw();
+
+ // Loop through each pixel in the motion bitmap data
+ var flyX:int = -1;
+ var flyY:int = -1;
+ for (var y:int = motionBitmap.height; y--; )
+ {
+ for (var x:int = motionBitmap.width; x--; )
+ {
+ // If this pixel has motion set this as a point for the flies to move to
+ if (motionBitmap.getPixel(x, y) == 0xFFFFFF)
+ {
+ flyX = x * MOTION_SCALE;
+ flyY = y * MOTION_SCALE;
+ break;
+ }
+ }
+ }
+
+ // Loop through each fly in the swarm
+ for (var i:int = flies; i--; )
+ {
+ // Fly the fly towards the motion point
+ var fly:SwarmFly = swarm.getChildAt(i) as SwarmFly;
+ fly.flyTo(flyX, flyY);
+
+ // Limit the fly to within bounds of the source image
+ if (fly.x < 0) fly.x = 0;
+ if (fly.y < 0) fly.y = 0;
+ if (fly.x > rect.width) fly.x = rect.width;
+ if (fly.y > rect.height) fly.y = rect.height;
+ }
+
+ // Draw the swarm over the source image
+ targetBitmap.lock();
+ targetBitmap.copyPixels(sourceBitmap, rect, point);
+ targetBitmap.draw(swarm);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the swarm effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the flies from the swarm sprite
+ for (var i:int = flies; i--; ) swarm.removeChildAt(i);
+ swarm = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/motion/SwarmFly.as b/webcam/webcam/effects/motion/SwarmFly.as new file mode 100755 index 0000000..a7cfe62 --- /dev/null +++ b/webcam/webcam/effects/motion/SwarmFly.as @@ -0,0 +1,122 @@ +/**
+ * Neave Webcam // Swarm Fly
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.motion
+{
+ import flash.display.*;
+ import flash.filters.*;
+
+ final internal class SwarmFly extends Shape
+ {
+ private const MAX_BOREDOM:int = 10;
+ private const BOREDOM_TIME:int = 20;
+ private const MAX_DIST:int = 8000;
+ private const BORED_DIST:int = 30;
+
+ private var x0:Number;
+ private var y0:Number;
+ private var size:Number;
+ private var speed:Number;
+ private var boredom:int;
+ private var wobbleAngle:Number;
+ private var wobbleDist:Number;
+ private var wobbleStep:Number;
+
+ /**
+ * Creates a fly graphic to be used with the swarm effect
+ *
+ * @param x The starting position of the fly on the x-axis
+ * @param y The starting position of the fly on the y-axis
+ */
+ public function SwarmFly(x:Number = 0, y:Number = 0, size:Number = 1)
+ {
+ this.x = x0 = x;
+ this.y = y0 = y;
+ this.size = size;
+
+ createFly();
+ }
+
+ /**
+ * Sets up the fly and its initial properties
+ */
+ private function createFly():void
+ {
+ // This fly's movement speed and initial boredom threshold
+ speed = Math.random() * 20 + 10;
+ boredom = Math.floor(Math.random() * (MAX_BOREDOM + BOREDOM_TIME));
+
+ // This fly's wobbling amount as it flies
+ wobbleAngle = Math.random() * Math.PI;
+ wobbleDist = Math.random() * 2.5 + 0.5;
+ wobbleStep = evenRandom() * 2;
+
+ // Draw the fly shape, a black circle with a black glow
+ graphics.beginFill(0x000000);
+ graphics.drawCircle(0, 0, size);
+ filters = [ new GlowFilter(0x000000, 1, 6, 6, 2, 2, false, false) ];
+ cacheAsBitmap = true;
+ }
+
+ /**
+ * Generates a random number between -0.5 and 0.5
+ */
+ private function evenRandom():Number
+ {
+ return Math.random() - 0.5;
+ }
+
+ /**
+ * Moves the fly towards the specified position
+ *
+ * @param x The position to move to on the x-axis
+ * @param y The position to move to on the y-axis
+ */
+ internal function flyTo(x:int, y:int):void
+ {
+ var dx:int = this.x - x;
+ var dy:int = this.y - y;
+ if (boredom > MAX_BOREDOM || dx * dx + dy * dy > MAX_DIST)
+ {
+ // Fly around if the fly is too bored or too far away
+ this.x += (x0 - this.x) / speed;
+ this.y += (y0 - this.y) / speed;
+
+ // Flying around reduces boredom
+ if (boredom > 0) boredom--;
+
+ // Not bored any more, reset boredom threshold
+ if (boredom == MAX_BOREDOM) boredom = 0;
+ }
+ else if (x >=0 || y >= 0)
+ {
+ // Fly isn't bored yet so moves towards the motion
+ this.x += (x - this.x) / speed / 2;
+ this.y += (y - this.y) / speed / 2;
+
+ // Boredom increases until the fly is totally bored and flies off
+ if (boredom < MAX_BOREDOM) boredom++;
+ else
+ {
+ // Bored now, so fly away somewhere for a time
+ x0 = x + evenRandom() * BORED_DIST;
+ y0 = y + evenRandom() * BORED_DIST;
+ boredom = MAX_BOREDOM + Math.ceil(evenRandom() * BOREDOM_TIME);
+ }
+ }
+
+ // Wobble the fly's movement
+ wobbleAngle += wobbleStep;
+ this.x += Math.sin(wobbleAngle) * wobbleDist;
+ this.y += Math.cos(wobbleAngle / 3) * wobbleDist;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/pixel/ASCIIEffect.as b/webcam/webcam/effects/pixel/ASCIIEffect.as new file mode 100755 index 0000000..cd8e8d8 --- /dev/null +++ b/webcam/webcam/effects/pixel/ASCIIEffect.as @@ -0,0 +1,225 @@ +/**
+ * Neave Webcam // ASCII Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+ import flash.filters.*;
+ import flash.geom.*;
+ import flash.system.*;
+ import flash.text.*;
+ import com.neave.webcam.effects.*;
+
+ public class ASCIIEffect extends AbstractEffect
+ {
+ private const FONT_NAME:String = "_typewriter";
+ private const FONT_SIZE:int = 10;
+ private const FONT_COLOR:int = 0x33FF33;
+ private const FONT_SPACING:int = 2;
+ private const FONT_WIN_LEADING:int = -8;
+ private const FONT_MAC_LEADING:int = -6;
+ private const CHARS_WIDE:int = 39;
+ private const MIN_ASCII_CHAR:uint = 32;
+ private const MAX_ASCII_CHAR:uint = 126;
+
+ private var flipChars:Boolean;
+ private var smallBitmap:BitmapData;
+ private var smallMatrix:Matrix;
+ private var textBitmap:BitmapData;
+ private var textfield:TextField;
+ private var textMatrix:Matrix;
+ private var flipMatrix:Matrix;
+ private var charsX:int;
+ private var charsY:int;
+ private var total:int;
+ private var textFormat:TextFormat;
+ private var chars:Array;
+ private var blur:BlurFilter;
+
+ /**
+ * Creates a text-based effect where each pixel is drawn as a letter from the ASCII character table
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param flipChars Flips the ASCII characters horizontally, useful if using a mirrored webcam as the source object
+ */
+ public function ASCIIEffect(source:IBitmapDrawable, targetBitmap:BitmapData, flipChars:Boolean = true)
+ {
+ super(source, targetBitmap, "ASCII");
+ this.flipChars = flipChars;
+
+ createASCII();
+ }
+
+ /**
+ * Sets up the ASCII effect
+ */
+ private function createASCII():void
+ {
+ // Increase contrast
+ color = new ColorTransform(2, 2, 2, 1, -100, -100, -100);
+
+ // Create the main textfield
+ var fmt:TextFormat = new TextFormat(FONT_NAME, FONT_SIZE, FONT_COLOR);
+ fmt.letterSpacing = FONT_SPACING;
+ fmt.leading = Capabilities.version.substr(0, 3) == "MAC" ? FONT_MAC_LEADING : FONT_WIN_LEADING;
+ textfield = new TextField();
+ textfield.defaultTextFormat = fmt;
+ textfield.autoSize = TextFieldAutoSize.LEFT;
+
+ // Get the ASCII characters in order of brightness
+ chars = getOrderedChars();
+ total = chars.length - 1;
+
+ // Create a bitmap to hold the textfield
+ textBitmap = targetBitmap.clone();
+ textMatrix = new Matrix();
+ textMatrix.translate(3, 0);
+
+ // Create a smaller, lower resolution bitmap to sample pixels from
+ smallBitmap = new BitmapData(CHARS_WIDE, Math.round(CHARS_WIDE * rect.height / rect.width), false, 0xFF000000);
+ charsX = smallBitmap.width;
+ charsY = smallBitmap.height;
+ smallMatrix = new Matrix();
+ smallMatrix.scale(charsX / rect.width, charsY / rect.height);
+
+ // If flip flag is true, reverse the bitmaps horizontally
+ flipMatrix = new Matrix();
+ flipMatrix.scale(rect.width / 320, rect.height / 240);
+ if (flipChars)
+ {
+ flipMatrix.scale(-1, 1);
+ flipMatrix.translate(rect.width, 0);
+ smallMatrix.scale(-1, 1);
+ smallMatrix.translate(charsX, 0);
+ }
+
+ // Use a blur filter to add a slight glow behind the characters
+ blur = new BlurFilter(4, 4, 1);
+ }
+
+ /**
+ * Generates an array of ASCII characters in order of pixel brightness
+ *
+ * @return An array of characters ordered by pixel brightness
+ */
+ private function getOrderedChars():Array
+ {
+ // Create an array containing character and its brightness
+ var order:Array = new Array();
+ for (var i:int = MIN_ASCII_CHAR; i < MAX_ASCII_CHAR; i++)
+ {
+ var c:String = String.fromCharCode(i);
+ order.push( { char:c, level:getCharBrightness(c) } );
+ }
+
+ // Sort the characters in order of descending brightness
+ order.sortOn("level", Array.NUMERIC | Array.DESCENDING);
+
+ // Return a new array containing only the characters in order
+ var list:Array = new Array();
+ for (i = order.length; i--; ) list.push(order[i].char);
+ return list;
+ }
+
+ /**
+ * Calculates the pixel brightness a character
+ *
+ * @param char The single ASCII character to test for brightness level
+ * @return A number between 0 and 1 indicating the amount of brightness
+ */
+ private function getCharBrightness(char:String):Number
+ {
+ // Create a temporary textfield to hold this character
+ var tf:TextField = new TextField();
+ tf.defaultTextFormat = new TextFormat(FONT_NAME, FONT_SIZE, 0x000000);
+ tf.text = char.charAt();
+ tf.autoSize = TextFieldAutoSize.LEFT;
+
+ // Determine the width and height of this character
+ var charWidth:int = Math.ceil(tf.width);
+ var charHeight:int = Math.ceil(tf.height);
+
+ // Create a temporary bitmap data to draw this character into
+ var charBitmap:BitmapData = new BitmapData(charWidth, charHeight, false, 0xFFFFFFFF);
+ charBitmap.draw(tf);
+
+ // Loop through each pixel in this character's bitmap data
+ var level:int = 0;
+ for (var y:int = charHeight; y--; )
+ {
+ for (var x:int = charWidth; x--; )
+ {
+ // If this pixel is bright enough, add it to the overall brightness level
+ if (charBitmap.getPixel(x, y) > 0x808080) level++;
+ }
+ }
+
+ // Return the brightness level as a percentage of the whole character area
+ return level / (charWidth * charHeight);
+ }
+
+ /**
+ * Converts a colour value to an averaged monochrome (greyscale) value
+ *
+ * @param col The colour to convert to monochrome
+ * @return The averaged monochrome value
+ */
+ private function getMonochrome(col:uint):uint
+ {
+ // Add the red, green and blue components together and return the average
+ return 0xFF - (((col >> 16) & 0xFF) + ((col >> 8) & 0xFF) + (col & 0xFF)) / 3;
+ }
+
+ /**
+ * Draws the ASCII effect
+ */
+ override public function draw():void
+ {
+ // Generate a lower resolution bitmap data to sample pixels from
+ smallBitmap.draw(source, smallMatrix, color);
+
+ // Create the ASCII textfield from each pixel
+ var str:String = "";
+ for (var y:int = 0; y < charsY; y++)
+ {
+ for (var x:int = 0; x < charsX; x++)
+ {
+ // Get the monochrome pixel value and convert it to an ASCII character
+ str += chars[int(getMonochrome(smallBitmap.getPixel(x, y)) / 0xFF * total)];
+ }
+ str += "\r\n"; // New line
+ }
+
+ // Draw the new ASCII textfield into the text bitmap data with a blurred background glow
+ textfield.text = str;
+ textBitmap.fillRect(rect, 0xFF000000);
+ textBitmap.draw(textfield, textMatrix);
+ sourceBitmap.applyFilter(textBitmap, rect, point, blur);
+ sourceBitmap.draw(textBitmap, null, null, BlendMode.ADD);
+ targetBitmap.draw(sourceBitmap, flipMatrix);
+ }
+
+ /**
+ * Removes the ASCII effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ smallBitmap.dispose();
+ smallBitmap = null;
+ textBitmap.dispose();
+ textBitmap = null;
+ textfield = null;
+ chars = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/pixel/HalftoneDot.as b/webcam/webcam/effects/pixel/HalftoneDot.as new file mode 100755 index 0000000..4f4fb40 --- /dev/null +++ b/webcam/webcam/effects/pixel/HalftoneDot.as @@ -0,0 +1,33 @@ +/**
+ * Neave Webcam // Halftone Dot
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+
+ final internal class HalftoneDot extends Shape
+ {
+ /**
+ * Draws a halftone dot shape to be used with the halftone effect
+ *
+ * @param x The position of the dot on the x-axis
+ * @param y The position of the dot on the y-axis
+ * @param radius The radius of the dot
+ */
+ public function HalftoneDot(x:Number = 0, y:Number = 0, radius:Number = 1)
+ {
+ this.x = x;
+ this.y = y;
+ graphics.beginFill(0x000000);
+ graphics.drawCircle(0, 0, radius);
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/pixel/HalftoneEffect.as b/webcam/webcam/effects/pixel/HalftoneEffect.as new file mode 100755 index 0000000..0b9cf3c --- /dev/null +++ b/webcam/webcam/effects/pixel/HalftoneEffect.as @@ -0,0 +1,135 @@ +/**
+ * Neave Webcam // Halftone Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class HalftoneEffect extends AbstractEffect
+ {
+ private var dotsWide:int;
+ private var invert:Boolean;
+ private var smallBitmap:BitmapData;
+ private var smallMatrix:Matrix;
+ private var halftone:Sprite;
+ private var dotsX:int;
+ private var dotsY:int;
+ private var size:Number;
+
+ /**
+ * Creates a halftone effect where each pixel is drawn as a variably-sized black dot, as used in the printing process
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param dotsWide The number of dots to use in width
+ * @param invert Inverts the halftone effect so bright pixels create large dots
+ */
+ public function HalftoneEffect(source:IBitmapDrawable, targetBitmap:BitmapData, dotsWide:int = 40, invert:Boolean = false)
+ {
+ super(source, targetBitmap, "Halftone");
+ this.dotsWide = dotsWide < 1 ? 1: dotsWide;
+ this.invert = invert;
+
+ createHalftone();
+ }
+
+ /**
+ * Sets up the halftone effect
+ */
+ private function createHalftone():void
+ {
+ // Increase contrast
+ color = new ColorTransform(1.5, 1.5, 1.5, 1, -50, -50, -50);
+
+ // Create a smaller, lower resolution bitmap to sample pixels from
+ smallBitmap = new BitmapData(dotsWide, Math.round(dotsWide * rect.height / rect.width), false, 0xFF000000);
+ dotsX = smallBitmap.width;
+ dotsY = smallBitmap.height;
+ smallMatrix = new Matrix();
+ smallMatrix.scale(dotsX / rect.width, dotsY / rect.height);
+ size = rect.width / dotsX;
+
+ // Create a sprite containing all the halftone dots needed
+ halftone = new Sprite();
+ for (var y:int = dotsY; y--; )
+ {
+ for (var x:int = dotsX; x--; )
+ {
+ // Position each halftone dot, alternating the y-axis position between on pixel and halfway between pixels
+ halftone.addChild(new HalftoneDot((x + 0.25 + (y % 2) * 0.5) * size, (y + 0.5) * size, size));
+ }
+ }
+ }
+
+ /**
+ * Converts a colour value to an averaged monochrome (greyscale) value
+ *
+ * @param col The colour to convert to monochrome
+ * @param inv Whether to invert the monochrome value
+ * @return The averaged monochrome value
+ */
+ private function getMonochrome(col:uint, inv:Boolean):uint
+ {
+ // Add the red, green and blue components together and return the average
+ var mono:uint = (((col >> 16) & 0xFF) + ((col >> 8) & 0xFF) + (col & 0xFF)) / 3;
+ if (inv) return mono;
+ else return 0xFF - mono;
+ }
+
+ /**
+ * Draws the halftone effect
+ */
+ override public function draw():void
+ {
+ // Generate a lower resolution bitmap data to sample pixels from
+ smallBitmap.draw(source, smallMatrix, color);
+
+ // Create the halftone dots from each pixel
+ var n:int = 0;
+ for (var y:int = dotsY; y--; )
+ {
+ for (var x:int = dotsX; x--; )
+ {
+ // Average this pixel's colour to a greyscale value
+ var w:Number = getMonochrome(smallBitmap.getPixel(x, y), invert) / 0xFF * Math.SQRT2 * size;
+
+ // Set this dot's size, alternating the y-axis position between on pixel and halfway between pixels
+ var d:HalftoneDot = halftone.getChildAt(n) as HalftoneDot;
+ d.width = d.height = (y % 2 == 0 || n == 0) ? w : (w + halftone.getChildAt(n - 1).width) / 2; // Average pixel values if this y-axis position is between pixels
+ n++;
+ }
+ }
+
+ // Draw the new halftone dots
+ targetBitmap.lock();
+ targetBitmap.fillRect(rect, 0xFFFFFFFF);
+ targetBitmap.draw(halftone);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the halftone effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the halftone dots
+ for (var i:int = dotsX * dotsY; i--; ) halftone.removeChildAt(i);
+ halftone = null;
+
+ smallBitmap.dispose();
+ smallBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/pixel/PixelateEffect.as b/webcam/webcam/effects/pixel/PixelateEffect.as new file mode 100755 index 0000000..8ff94d5 --- /dev/null +++ b/webcam/webcam/effects/pixel/PixelateEffect.as @@ -0,0 +1,75 @@ +/**
+ * Neave Webcam // Pixelate Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class PixelateEffect extends AbstractEffect
+ {
+ private var pixelsWide:int;
+ private var smallBitmap:BitmapData;
+ private var targetMatrix:Matrix;
+
+ /**
+ * Creates a low-resolution effect where pixels appear large
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param pixelsWide The number of pixels to use in width
+ */
+ public function PixelateEffect(source:IBitmapDrawable, targetBitmap:BitmapData, pixelsWide:int = 20)
+ {
+ super(source, targetBitmap, "Pixelate");
+ this.pixelsWide = pixelsWide < 1 ? 1 : pixelsWide;
+
+ createPixelate();
+ }
+
+ /**
+ * Sets up the pixelate effect
+ */
+ private function createPixelate():void
+ {
+ // Create a low resolution bitmap data
+ smallBitmap = new BitmapData(pixelsWide, Math.round(pixelsWide * rect.height / rect.width), false, 0xFF000000);
+
+ // Set up scaling of bitmaps from large to small to large again
+ var sx:Number = smallBitmap.width / rect.width;
+ var sy:Number = smallBitmap.height / rect.height;
+ sourceMatrix.scale(sx, sy);
+ targetMatrix = new Matrix();
+ targetMatrix.scale(1 / sx, 1 / sy);
+ }
+
+ /**
+ * Draws the pixelate effect
+ */
+ override public function draw():void
+ {
+ // Resize small then resize large
+ smallBitmap.draw(source, sourceMatrix);
+ targetBitmap.draw(smallBitmap, targetMatrix);
+ }
+
+ /**
+ * Removes the pixelate effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+ smallBitmap.dispose();
+ smallBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/pixel/RGBEffect.as b/webcam/webcam/effects/pixel/RGBEffect.as new file mode 100755 index 0000000..4d2b2ff --- /dev/null +++ b/webcam/webcam/effects/pixel/RGBEffect.as @@ -0,0 +1,126 @@ +/**
+ * Neave Webcam // Red Green Blue Effect
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+ import flash.geom.*;
+ import com.neave.webcam.effects.*;
+
+ public class RGBEffect extends AbstractEffect
+ {
+ private const COLORS:Array = [0xFF0000, 0x00FF00, 0x0000FF];
+
+ private var pixelsWide:int;
+ private var smallBitmap:BitmapData;
+ private var smallMatrix:Matrix;
+ private var pixels:Sprite;
+ private var pixelsX:int;
+ private var pixelsY:int;
+ private var size:Number;
+
+ /**
+ * Creates a low-resolution effect where each pixel is split into its red, green and blue components
+ *
+ * @param source The source object to use for the effect
+ * @param targetBitmap The target bitmap data to draw the resulting effect into
+ * @param pixelsWide The number of pixels to use in width
+ */
+ public function RGBEffect(source:IBitmapDrawable, targetBitmap:BitmapData, pixelsWide:int = 40)
+ {
+ super(source, targetBitmap, "RGB");
+ this.pixelsWide = pixelsWide < 3 ? 3 : pixelsWide;
+
+ createRGB();
+ }
+
+ /**
+ * Sets up the RGB effect
+ */
+ private function createRGB():void
+ {
+ // Create a smaller, lower resolution bitmap to sample pixels from
+ smallBitmap = new BitmapData(pixelsWide, Math.round(pixelsWide * rect.height / rect.width), false, 0xFF000000);
+ pixelsX = smallBitmap.width;
+ pixelsY = smallBitmap.height;
+ smallMatrix = new Matrix();
+ smallMatrix.scale(pixelsX / rect.width, pixelsY / rect.height);
+ size = rect.width / pixelsX;
+
+ // Create a sprite containing all the RGB pixels needed
+ pixels = new Sprite();
+ for (var y:int = pixelsY; y--; )
+ {
+ for (var x:int = pixelsX; x--; )
+ {
+ // Position each RGB pixel and set its colour to either red, green or blue
+ pixels.addChild(new RGBPixel((x + 0.5) * size, (y + 0.5) * size, COLORS[x % 3], size));
+ }
+ }
+ }
+
+ /**
+ * Draws the RGB effect
+ */
+ override public function draw():void
+ {
+ // Generate a lower resolution bitmap data to sample pixels from
+ smallBitmap.draw(source, smallMatrix, color);
+
+ // Create the RGB pixels from each pixel
+ var n:int = 0;
+ for (var y:int = pixelsY; y--; )
+ {
+ for (var x:int = pixelsX; x--; )
+ {
+ // Set the brightness of this RGB pixel
+ var c:uint = smallBitmap.getPixel(x, y);
+ var p:RGBPixel = pixels.getChildAt(n++) as RGBPixel;
+ switch (x % 3)
+ {
+ case 0: // Red
+ p.alpha = ((c >> 16) & 0xFF) / 0xFF;
+ break;
+
+ case 1: // Green
+ p.alpha = ((c >> 8) & 0xFF) / 0xFF;
+ break;
+
+ case 2: // Blue
+ p.alpha = (c & 0xFF) / 0xFF;
+ break;
+ }
+ }
+ }
+
+ // Draw the new RGB pixels
+ targetBitmap.lock();
+ targetBitmap.fillRect(rect, 0xFF000000);
+ targetBitmap.draw(pixels);
+ targetBitmap.unlock();
+ }
+
+ /**
+ * Removes the RGB effect and all other referenced objects
+ */
+ override public function destroy():void
+ {
+ super.destroy();
+
+ // Remove all the pixels
+ for (var i:int = pixelsX * pixelsY; i--; ) pixels.removeChildAt(i);
+ pixels = null;
+
+ smallBitmap.dispose();
+ smallBitmap = null;
+ }
+ }
+}
\ No newline at end of file diff --git a/webcam/webcam/effects/pixel/RGBPixel.as b/webcam/webcam/effects/pixel/RGBPixel.as new file mode 100755 index 0000000..ababb10 --- /dev/null +++ b/webcam/webcam/effects/pixel/RGBPixel.as @@ -0,0 +1,34 @@ +/**
+ * Neave Webcam // Red Green Blue Pixel
+ *
+ * Copyright (C) 2008 Paul Neave
+ * http://www.neave.com/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
+ */
+
+package com.neave.webcam.effects.pixel
+{
+ import flash.display.*;
+
+ final internal class RGBPixel extends Shape
+ {
+ /**
+ * Draws a simple square graphic to be used with the RGB effect
+ *
+ * @param x The position of the pixel on the x-axis
+ * @param y The position of the pixel on the y-axis
+ * @param color The colour of the pixel
+ * @param size The size (width and height) of the pixel
+ */
+ public function RGBPixel(x:int = 0, y:int = 0, color:uint = 0, size:Number = 1)
+ {
+ this.x = x - size / 2;
+ this.y = y - size / 2;
+ graphics.beginFill(color);
+ graphics.drawRect(0, 0, size, size);
+ }
+ }
+}
\ No newline at end of file |
