오윤석

GIFEncoder npm에서 관리

This diff is collapsed. Click to expand it.
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
19 "webpack-cli": "^4.6.0" 19 "webpack-cli": "^4.6.0"
20 }, 20 },
21 "dependencies": { 21 "dependencies": {
22 - "@babel/plugin-proposal-class-properties": "^7.13.0" 22 + "@babel/plugin-proposal-class-properties": "^7.13.0",
23 + "gifencoder": "^2.0.1",
24 + "stream": "0.0.2"
23 } 25 }
24 } 26 }
......
1 -import GIF from "./lib/GIFEncoder"; 1 +import GIF from "gifencoder";
2 2
3 class GifGenerator { 3 class GifGenerator {
4 constructor(canvas) { 4 constructor(canvas) {
...@@ -7,32 +7,22 @@ class GifGenerator { ...@@ -7,32 +7,22 @@ class GifGenerator {
7 this.height = canvas.getHeight(); 7 this.height = canvas.getHeight();
8 this.gif = new GIF(this.width, this.height); 8 this.gif = new GIF(this.width, this.height);
9 9
10 - this.gif.writeHeader(); 10 + this.gif.start();
11 this.gif.setTransparent(null); 11 this.gif.setTransparent(null);
12 this.gif.setRepeat(0); 12 this.gif.setRepeat(0);
13 this.gif.setQuality(10); 13 this.gif.setQuality(10);
14 - this.gif.setDither(false);
15 - this.gif.setGlobalPalette(false);
16 } 14 }
17 15
18 addFrame(delay = 0) { 16 addFrame(delay = 0) {
19 this.gif.setDelay(delay); 17 this.gif.setDelay(delay);
20 - this.gif.addFrame( 18 + this.gif.addFrame(this.canvas.getContext());
21 - this.canvas.getContext().getImageData(0, 0, this.width, this.height).data
22 - );
23 } 19 }
24 20
25 render() { 21 render() {
26 this.gif.finish(); 22 this.gif.finish();
27 - const stream = this.gif.stream(); 23 + const byte = new Uint8Array(this.gif.out.data);
28 24
29 - let bytes = []; 25 + return new Blob([byte], { type: "image/gif" });
30 - stream.pages.map((page) => {
31 - bytes = bytes.concat([...page]);
32 - });
33 - bytes = new Uint8Array(bytes);
34 -
35 - return new Blob([bytes], { type: "image/gif" });
36 } 26 }
37 } 27 }
38 28
......
This diff is collapsed. Click to expand it.
1 -/*
2 - LZWEncoder.js
3 -
4 - Authors
5 - Kevin Weiner (original Java version - kweiner@fmsware.com)
6 - Thibault Imbert (AS3 version - bytearray.org)
7 - Johan Nordberg (JS version - code@johan-nordberg.com)
8 -
9 - Acknowledgements
10 - GIFCOMPR.C - GIF Image compression routines
11 - Lempel-Ziv compression based on 'compress'. GIF modifications by
12 - David Rowley (mgardi@watdcsu.waterloo.edu)
13 - GIF Image compression - modified 'compress'
14 - Based on: compress.c - File compression ala IEEE Computer, June 1984.
15 - By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
16 - Jim McKie (decvax!mcvax!jim)
17 - Steve Davies (decvax!vax135!petsd!peora!srd)
18 - Ken Turkowski (decvax!decwrl!turtlevax!ken)
19 - James A. Woods (decvax!ihnp4!ames!jaw)
20 - Joe Orost (decvax!vax135!petsd!joe)
21 -*/
22 -
23 -var EOF = -1;
24 -var BITS = 12;
25 -var HSIZE = 5003; // 80% occupancy
26 -var masks = [
27 - 0x0000,
28 - 0x0001,
29 - 0x0003,
30 - 0x0007,
31 - 0x000f,
32 - 0x001f,
33 - 0x003f,
34 - 0x007f,
35 - 0x00ff,
36 - 0x01ff,
37 - 0x03ff,
38 - 0x07ff,
39 - 0x0fff,
40 - 0x1fff,
41 - 0x3fff,
42 - 0x7fff,
43 - 0xffff,
44 -];
45 -
46 -function LZWEncoder(width, height, pixels, colorDepth) {
47 - var initCodeSize = Math.max(2, colorDepth);
48 -
49 - var accum = new Uint8Array(256);
50 - var htab = new Int32Array(HSIZE);
51 - var codetab = new Int32Array(HSIZE);
52 -
53 - var cur_accum,
54 - cur_bits = 0;
55 - var a_count;
56 - var free_ent = 0; // first unused entry
57 - var maxcode;
58 -
59 - // block compression parameters -- after all codes are used up,
60 - // and compression rate changes, start over.
61 - var clear_flg = false;
62 -
63 - // Algorithm: use open addressing double hashing (no chaining) on the
64 - // prefix code / next character combination. We do a variant of Knuth's
65 - // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
66 - // secondary probe. Here, the modular division first probe is gives way
67 - // to a faster exclusive-or manipulation. Also do block compression with
68 - // an adaptive reset, whereby the code table is cleared when the compression
69 - // ratio decreases, but after the table fills. The variable-length output
70 - // codes are re-sized at this point, and a special CLEAR code is generated
71 - // for the decompressor. Late addition: construct the table according to
72 - // file size for noticeable speed improvement on small files. Please direct
73 - // questions about this implementation to ames!jaw.
74 - var g_init_bits, ClearCode, EOFCode;
75 -
76 - // Add a character to the end of the current packet, and if it is 254
77 - // characters, flush the packet to disk.
78 - function char_out(c, outs) {
79 - accum[a_count++] = c;
80 - if (a_count >= 254) flush_char(outs);
81 - }
82 -
83 - // Clear out the hash table
84 - // table clear for block compress
85 - function cl_block(outs) {
86 - cl_hash(HSIZE);
87 - free_ent = ClearCode + 2;
88 - clear_flg = true;
89 - output(ClearCode, outs);
90 - }
91 -
92 - // Reset code table
93 - function cl_hash(hsize) {
94 - for (var i = 0; i < hsize; ++i) htab[i] = -1;
95 - }
96 -
97 - function compress(init_bits, outs) {
98 - var fcode, c, i, ent, disp, hsize_reg, hshift;
99 -
100 - // Set up the globals: g_init_bits - initial number of bits
101 - g_init_bits = init_bits;
102 -
103 - // Set up the necessary values
104 - clear_flg = false;
105 - n_bits = g_init_bits;
106 - maxcode = MAXCODE(n_bits);
107 -
108 - ClearCode = 1 << (init_bits - 1);
109 - EOFCode = ClearCode + 1;
110 - free_ent = ClearCode + 2;
111 -
112 - a_count = 0; // clear packet
113 -
114 - ent = nextPixel();
115 -
116 - hshift = 0;
117 - for (fcode = HSIZE; fcode < 65536; fcode *= 2) ++hshift;
118 - hshift = 8 - hshift; // set hash code range bound
119 - hsize_reg = HSIZE;
120 - cl_hash(hsize_reg); // clear hash table
121 -
122 - output(ClearCode, outs);
123 -
124 - outer_loop: while ((c = nextPixel()) != EOF) {
125 - fcode = (c << BITS) + ent;
126 - i = (c << hshift) ^ ent; // xor hashing
127 - if (htab[i] === fcode) {
128 - ent = codetab[i];
129 - continue;
130 - } else if (htab[i] >= 0) {
131 - // non-empty slot
132 - disp = hsize_reg - i; // secondary hash (after G. Knott)
133 - if (i === 0) disp = 1;
134 - do {
135 - if ((i -= disp) < 0) i += hsize_reg;
136 - if (htab[i] === fcode) {
137 - ent = codetab[i];
138 - continue outer_loop;
139 - }
140 - } while (htab[i] >= 0);
141 - }
142 - output(ent, outs);
143 - ent = c;
144 - if (free_ent < 1 << BITS) {
145 - codetab[i] = free_ent++; // code -> hashtable
146 - htab[i] = fcode;
147 - } else {
148 - cl_block(outs);
149 - }
150 - }
151 -
152 - // Put out the final code.
153 - output(ent, outs);
154 - output(EOFCode, outs);
155 - }
156 -
157 - function encode(outs) {
158 - outs.writeByte(initCodeSize); // write "initial code size" byte
159 - remaining = width * height; // reset navigation variables
160 - curPixel = 0;
161 - compress(initCodeSize + 1, outs); // compress and write the pixel data
162 - outs.writeByte(0); // write block terminator
163 - }
164 -
165 - // Flush the packet to disk, and reset the accumulator
166 - function flush_char(outs) {
167 - if (a_count > 0) {
168 - outs.writeByte(a_count);
169 - outs.writeBytes(accum, 0, a_count);
170 - a_count = 0;
171 - }
172 - }
173 -
174 - function MAXCODE(n_bits) {
175 - return (1 << n_bits) - 1;
176 - }
177 -
178 - // Return the next pixel from the image
179 - function nextPixel() {
180 - if (remaining === 0) return EOF;
181 - --remaining;
182 - var pix = pixels[curPixel++];
183 - return pix & 0xff;
184 - }
185 -
186 - function output(code, outs) {
187 - cur_accum &= masks[cur_bits];
188 -
189 - if (cur_bits > 0) cur_accum |= code << cur_bits;
190 - else cur_accum = code;
191 -
192 - cur_bits += n_bits;
193 -
194 - while (cur_bits >= 8) {
195 - char_out(cur_accum & 0xff, outs);
196 - cur_accum >>= 8;
197 - cur_bits -= 8;
198 - }
199 -
200 - // If the next entry is going to be too big for the code size,
201 - // then increase it, if possible.
202 - if (free_ent > maxcode || clear_flg) {
203 - if (clear_flg) {
204 - maxcode = MAXCODE((n_bits = g_init_bits));
205 - clear_flg = false;
206 - } else {
207 - ++n_bits;
208 - if (n_bits == BITS) maxcode = 1 << BITS;
209 - else maxcode = MAXCODE(n_bits);
210 - }
211 - }
212 -
213 - if (code == EOFCode) {
214 - // At EOF, write the rest of the buffer.
215 - while (cur_bits > 0) {
216 - char_out(cur_accum & 0xff, outs);
217 - cur_accum >>= 8;
218 - cur_bits -= 8;
219 - }
220 - flush_char(outs);
221 - }
222 - }
223 -
224 - this.encode = encode;
225 -}
226 -
227 -module.exports = LZWEncoder;
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.