Socket
Socket
Sign inDemoInstall

gif-frames

Package Overview
Dependencies
71
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.0 to 0.2.0

100

gif-frames.js
var path = require('path');
var MultiRange = require('multi-integer-range').MultiRange;
var getPixels = require('get-pixels');
var savePixels = require('save-pixels');
var fs = require('fs');
// https://stackoverflow.com/a/28203456
function numDigits (x) {
return (Math.log10((x ^ (x >> 31)) - (x >> 31)) | 0) + 1;
function nopromises () {
throw new Error(
'Promises not supported in your environment. ' +
'Use the callback argument or a Promise polyfill.'
);
}
// https://stackoverflow.com/a/2998822
function padNumber (num, size) {
var s = num + '';
while (s.length < size) {
s = '0' + s;
}
return s;
}
var brokenPromise = {
then: nopromises,
catch: nopromises
};

@@ -23,41 +21,71 @@ function gifFrames (options, callback) {

callback = callback || function () {};
var input = options.input;
if (!input) {
callback(new Error('"input" option is required.'));
var promise;
var resolve;
var reject;
if (typeof Promise === 'function') {
promise = new Promise(function (_resolve, _reject) {
resolve = function (res) {
callback(null, res);
_resolve(res);
};
reject = function (err) {
callback(err);
_reject(err);
};
});
} else {
promise = brokenPromise;
resolve = function (res) {
callback(null, res);
};
reject = callback;
}
var url = options.url;
if (!url) {
reject(new Error('"url" option is required.'));
return;
}
var filename = options.filename
|| (typeof input === 'string' ? path.basename(input) : '');
if (typeof input !== 'string' && !filename) {
callback(new Error('"filename" option is required for non-string inputs.'));
var frames = options.frames;
if (!frames && frames !== 0) {
reject(new Error('"frames" option is required.'));
return;
}
var filenameType = path.extname(filename).slice(1);
var outputType = options.outputType || filenameType || 'jpg';
var outputPathBase = filename
&& filenameType.toLowerCase() === outputType.toLowerCase()
&& filename.slice(0, -(outputType.length + 1))
|| filename;
var outputType = options.outputType || 'jpg';
var quality = options.quality;
getPixels(input, 'image/gif', function (err, pixels) {
var acceptedFrames = new MultiRange(frames);
getPixels(url, 'image/gif', function (err, pixels) {
if (err) {
callback(err);
reject(err);
return;
}
if (pixels.shape.length < 4) {
callback(new Error('Input should be multi-frame GIF.'));
reject(new Error('"url" input should be multi-frame GIF.'));
return;
}
var frameCount = pixels.shape[0];
var frameCountDigits = numDigits(frameCount);
for (var i = 0; i < frameCount; i++) {
savePixels(pixels.pick(i), outputType, {
quality: options.quality
}).pipe(fs.createWriteStream(
outputPathBase + '-' + padNumber(i, frameCountDigits) + '.' + outputType
));
var frameData = [];
for (var i = 0; i < pixels.shape[0]; i++) {
if (!acceptedFrames.has(i)) {
continue;
}
(function (frameIndex) {
frameData.push({
getImageStream: function () {
return savePixels(pixels.pick(frameIndex), outputType, {
quality: quality
});
},
frameIndex: frameIndex
});
})(i);
}
resolve(frameData);
});
return promise;
}
module.exports = gifFrames;
{
"name": "gif-frames",
"version": "0.1.0",
"version": "0.2.0",
"description": "Pure JavaScript tool for extracting GIF frames and saving to file",

@@ -30,4 +30,5 @@ "main": "gif-frames.js",

"get-pixels": "^3.3.0",
"multi-integer-range": "^3.0.0",
"save-pixels": "^2.3.4"
}
}

@@ -13,13 +13,62 @@ # gif-frames

Options:
* `input` (**required**): The pathname to the file, or an [in-memory Buffer](http://nodejs.org/api/buffer.html)
* ***TODO:*** `frames` (**required**): The set of frames to extract (currently extracts all)
* `filename` (*optional* if `input` is a pathname, **required** if `input` is a `Buffer`): The input file's name
* `outputType` (*optional*, default "jpg"): Type to use for output (see [`type`](https://github.com/scijs/save-pixels#requiresave-pixelsarray-type-options) for `save-pixels`)
### Options:
* `url` (**required**): The pathname to the file, or an [in-memory Buffer](http://nodejs.org/api/buffer.html)
* `frames` (**required**): The set of frames to extract. Can be one of:
- `'all'` (gets every frame)
- Any valid [`Initializer`](https://github.com/smikitky/node-multi-integer-range#initializers) accepted by the [multi-integer-range library](https://github.com/smikitky/node-multi-integer-range)
* `outputType` (*optional*, default `'jpg'`): Type to use for output (see [`type`](https://github.com/scijs/save-pixels#requiresave-pixelsarray-type-options) for `save-pixels`)
* `quality` (*optional*): Jpeg quality (see [`quality`](https://github.com/scijs/save-pixels#requiresave-pixelsarray-type-options) for `save-pixels`)
The optional callback is called if an error occurs, with the error object
as its only argument.
The callback accepts the arguments `(error, frameData)`.
Returns:
***TODO:*** A stream of the extracted frames
### Returns:
A `Promise` resolving to the `frameData` array (if promises are supported in the running environment)
## `frameData`
An array of objects of the form:
```javascript
{
getImageStream,
frameIndex
}
```
## Examples
Writing selected frames to the file system in Node:
```javascript
var gifFrames = require('gif-frames');
var fs = require('fs');
gifFrames(
{ url: 'image.gif', frames: '0-2,7', outputType: 'png' },
function (err, frameData) {
if (err) {
throw err;
}
frameData.forEach(function (frame) {
frame.getImageStream().pipe(fs.createWriteStream(
'image-' + frame.frameIndex + '.png'
));
});
}
);
```
Drawing first frame to canvas in browser (and using a `Promise`):
```javascript
var gifFrames = require('gif-frames');
gifFrames({ url: 'image.gif', frames: 0, outputType: 'canvas' })
.then(function (frameData) {
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
frameData[0].getImageStream().pipe(canvas);
}).catch(console.error.bind(console));
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc