Now a days, I was thinking about how to optimize an animated GIF image. And I’ve got some solutions from the following link.
Optimizing Animated GIFsI tried one thing, frame differenecing. I don’t know it conforms to the GIF specification. But it can be useful somehow.
요즘 GIF 애니메이션 최적화에 대해서 연구하고 있는데, 아래 사이트에서 유용한 정보들을 얻을 수 있었습니다.
Optimizing Animated GIFs그 중에 프레임 디퍼런싱을 만들어 보았습니다. GIF 스펙을 따르는지는 모르지만, 써먹을 데가 있을듯 하여…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | /* * This work is licensed under a Creative Commons Attribution 3.0 License. * http://creativecommons.org/licenses/by/3.0/ */ /* * FrameDifferencing * FrameDifferencing class compares two bitmaps and extracts different area * * @author: Han Sanghun (http://hangunsworld.com/blog) * @last modified: 2007-05-24 * @language version: ActionScript 3.0 */ package{ import flash.display.*; import flash.events.*; import flash.geom.*; import flash.text.*; public class FrameDifferencing extends MovieClip{ // image dimension private const WID:uint = 89; private const HGT:uint = 104; // source image 1 private var bd1:BitmapData; private var bmp1:Bitmap; // source image 2 private var bd2:BitmapData; private var bmp2:Bitmap; // compare image private var compare_bd:BitmapData; private var compare_bmp:Bitmap; // different area image private var diff_bd:BitmapData; private var diff_bmp:Bitmap; // result movieclip private var result_mc:MovieClip; private var result_bmp1:Bitmap; private var result_bmp2:Bitmap; /* * FrameDifferencing constructor */ public function FrameDifferencing(){ // original images bd1 = new BitmapData(WID, HGT, true, 0×00000000); bd2 = new BitmapData(WID, HGT, true, 0×00000000); bd1.draw(mc1); bd2.draw(mc2); bmp1 = new Bitmap(bd1); bmp2 = new Bitmap(bd2); // compare 2 images var returnObject:Object = bd1.compare(bd2); // cast returned Object to BitmapData // i don’t know this is right solution, but i have to do this to avoide type mismatch error on compile compare_bd = BitmapData(returnObject); compare_bmp = new Bitmap(compare_bd); addChild(compare_bmp); compare_bmp.x = 200; // hide same area from 2nd image diff_bd = bd2.clone(); var rect:Rectangle = new Rectangle(0, 0, WID, HGT); var pnt:Point = new Point(0, 0); diff_bd.copyChannel(compare_bd, rect, pnt, BitmapDataChannel.ALPHA, BitmapDataChannel.ALPHA); diff_bmp = new Bitmap(diff_bd); addChild(diff_bmp); diff_bmp.x = 300; // movieclip to view preview result_mc = new MovieClip(); result_mc.x = 400; addChild(result_mc); // 1st frame image result_bmp1 = new Bitmap(bd1); result_mc.addChild(result_bmp1); // 2nd frame image result_bmp2 = new Bitmap(diff_bd); result_mc.addChild(result_bmp2); result_bmp2.visible = false; // enterframe event for previewing result_mc.addEventListener(Event.ENTER_FRAME, showPreview); } /* * showPreview * just show/hide 2nd image to mimic previewing * GIF encoder is not yet completed */ private function showPreview(evt:Event):void{ result_bmp2.visible = !result_bmp2.visible; } } } |
비디오 코덱에서 널리 쓰이고 있는 motion estimation/compensation 의 러프한 버젼이군요~
용량을 줄이기 위해서 각 프레임의 일부분만을 인코딩하고, 나머지 공간은 이전 프레임의 데이터를 사용한다는 측면에서 보면 비슷한 개념이겠네요. GIF 쪽이 좀 더 간단한 구조이겠지만요 ^^