Showing
7 changed files
with
8 additions
and
243 deletions
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 | ... | ... |
gif-generator/src/lib/GIFEncoder.js
deleted
100644 → 0
This diff is collapsed. Click to expand it.
gif-generator/src/lib/LZWEncoder.js
deleted
100644 → 0
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; |
gif-generator/src/lib/NeuQuant.js
deleted
100644 → 0
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment