leather
v3.0.3
Published
A pure JS library for extracting image/video attributes such as width, height, size, and mime type
Downloads
2,326
Maintainers
Readme
Leather
Have you ever wished for the ability to retrieve image or video file attributes
such as width, height, size, and mime type in Node without having
to resort to external libraries such as ffprobe
?
Yeah, me too! This is why leather
was created.
At the moment, the only package that does something similar is
image-size
and while it does work well, it does not handle video formats.
How
leather
uses streams to read image and video files in byte-sized chunks.
As soon attributes have been extracted, the stream will be closed. Some file
formats have a well-defined fixed position in which these attributes
can be found, in those cases, leather
skips any bytes before that
position and reads only the bytes needed to extract attributes directly.
However, sometimes the byte offset of these attributes may vary, in these
scenarios leather
makes a best-effort attempt to read as few bytes as
possible to get to the good stuff!
Why
Before leather
, if you wanted to do something like this in Node
you would need to install image-size
to handle images and either
use ffprobe
directly or using some kind of wrapper package to
handle video files.
While I love ffprobe
for its capabilities, setting up a cross-platform
package requires some configuration. This package aims to solve that
by steering clear of any command-line tools which makes it more portable.
Node support
Stable Node versions from 14.18 and up are tested, Node 12.20 and up is supported.
Installation
Install the package locally using npm
:
npm install leather --save
Or using yarn
yarn add leather
Usage
After installing the package, it can be imported using commonjs:
const {readMediaAttributes} = require('leather');
Or using ES modules:
import {readMediaAttributes} from 'leather';
Then, it can be called on supported image and video formats:
console.log(readMediaAttributes('cat.jpg'));
// => {width: 200, height: 200, size: 40000, mime: 'image/jpeg'}
Buffer support
Starting from version 2.1.0, all readMediaAttributes
methods also accept Buffer
instances in addition to file paths:
const buffer = fs.readFileSync('cat.png');
console.log(readMediaAttributes(buffer));
// => {width: 200, height: 200, size: 40000, mime: 'image/jpeg'}
The width and height are pixel based. The size is the same as
fs.stat
.
If the width or height could not be extracted, they will default to 0
.
The mime type is also returned if found, otherwise undefined
.
Using specific extractors
If you are only using one or a few of the extractors, you can opt to require only the extractors you need, e.g. for jpg/jpeg using commonjs:
const {readFileSync} = require('fs');
const {readMediaAttributes} = require('leather/extractors/jpg');
console.log(readMediaAttributes('cat.jpg'));
console.log(readMediaAttributes(readFileSync('cat.jpg')));
// => {width: 200, height: 200, size: 40000, mime: 'image/jpeg'}
Or using ES modules:
import {readFileSync} from 'fs';
import {readMediaAttributes} from 'leather/extractors/jpg';
console.log(readMediaAttributes('cat.jpg'));
console.log(readMediaAttributes(readFileSync('cat.jpg')));
// => {width: 200, height: 200, size: 40000, mime: 'image/jpeg'}
Supported formats
All supported image and video formats can be found in the table below:
| format | extractor | mime type | |:---------|:-------------------------------|:------------------------------| | bmp | bmp | image/bmp | | dds | dds | image/vnd.ms-dds | | gif | gif | image/gif | | icns | icns | image/x-icns | | ico | ico | image/vnd.microsoft.icon | | cur | ico | image/vnd.microsoft.icon | | j2c | j2c | image/jp2 | | jp2 | j2c | image/jp2 | | jpg | jpg | image/jpeg | | ktx | ktx | image/ktx | | png | png | image/png | | apng | png | image/apng | | pfm | pnm | application/x-font-type1 | | pam | pnm | image/x-portable-arbitrarymap | | pbm | pnm | image/x-portable-bitmap | | pgm | pnm | image/x-portable-graymap | | ppm | pnm | image/x-portable-pixmap | | psd | psd | image/vnd.adobe.photoshop | | svg | svg | image/svg+xml | | tiff | tiff | image/tiff | | webp | webp | image/webp | | xpm | xpm | image/x-xpixmap | | xbm | xbm | image/x-xbitmap | | fit | fit | image/fits | | cel | cel | application/octet-stream | | hdr | hdr | image/vnd.radiance | | avi | avi | video/x-msvideo | | fli | fli | video/x-fli | | flc | fli | video/x-fli | | flv | flv | video/x-flv | | mng | png | video/x-mng | | mp4 | mp4 | video/mp4 | | m4v | mp4 | video/x-m4v | | mov | mp4 | video/quicktime | | ogv | ogv | video/ogg | | mkv | webm | video/x-matroska | | webm | webm | video/webm | | wmv | wmv | video/x-ms-wmv |
Changelog
Credits and other resources that saved my soul
- https://www.npmjs.com/package/image-size
- http://www.fastgraph.com/help/avi_header_format.html
- http://www.fastgraph.com/help/flic_header_format.html
- https://docs.microsoft.com/en-us/previous-versions/ms779632(v=vs.85)
- https://en.wikipedia.org/wiki/List_of_file_signatures
- https://www.fileformat.info/format/tiff/egff.htm#TIFF.FO
- http://netpbm.sourceforge.net/doc/#formats
- https://www.garykessler.net/library/file_sigs.html
- https://github.com/sannies/mp4parser/blob/c869d076e9cd42aba5a3e35d88827610dec6ca15/examples/src/main/java/com/google/code/mp4parser/example/GetHeight.java
- https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html