Convert / resize / transcode / down-sample photos & videos to be web-friendly
This is one of the core modules of thumbsup.github.io.
npm install thumbsup-downsize --save
This module requires the following binaries available in the system path, depending on the type of files you need to process:
- GraphicsMagick for processing images
- ImageMagick for HEIC support
- FFMpeg for processing videos
- Gifsicle for processing animated GIFs
To run the tests, you will also need
const downsize =const options = height: 100 width: 100downsize
Processes the image in
source and creates a new image in
The image is appropriately converted if needed based on the
target file extension.
You can specify the following options:
// proportionally resize the photo to a maximum heightopts = height: 300// proportionally resize the photo to a maximum widthopts = width: 300// resize and crop the photo to exactly height x width// the image will not be distortedopts = height: 100 width: 100
// quality between 0 and 100opts = quality: 80
You can overlay a transparent watermark over the final image:
opts =watermark:file: 'path/watermark.png' // transparent PNGposition: 'NorthEast' // position of the watermark
The possible values for
Repeatto repeat the watermark across the whole image
Centerto position the watermark in the middle
SouthEastto position the watermark along the edge
Note: watermarks are not compatible with cropped images.
watermark option will simply be ignored if both width and height are specified.
You can specify extra arguments that will be passed to GraphicsMagick. This only works with output arguments.
opts =args:'-unsharp 2 0.5 0.7 0''-modulate 120'
By default, only the first frame of an animated GIF is exported. You can keep the entire animation by specifying:
opts = animated: true
This offloads the processing of the image to Gifsicle. Note that:
- The destination file extension must be
- The only other supported parameters are
height(e.g. no watermarks)
- Cropping (specifying both width and height) is not supported and will throw an error
The flag is simply ignored if the source file is not a GIF.
Extract a single frame from the video in
source, and writes the image to
This method supports all the same options as
.image(), with the addition of:
opts =// take the screenshot at the very start of the videoseek: 0// take the screenshot after N second (default = 1)seek: 1// take the screenshot in the middle of the videoseek: -1
If seeking fails for any reason, the first frame is used instead.
Transcodes the video in
source to a web-friendly format and lower bitrate, and writes it in
You can specify the following options:
The default export format is
You can specify an export format by adding a
opts = format: 'mp4' // H264 encoderopts = format: 'webm' // VP9 encoder
Note: encoding as
webm is much slower.
The default behaviour is to use CRF (constant rate factor) to control the output quality.
The default value is
// value between 0 (worst) and 100 (best)opts = quality: 75
- the quality scale is not linear
- you will most likely want a value between 50% and 90%
- values over 90% can generate files larger than the original
Instead of CRF, you can specify a variable bitrate (a.k.a. average bitrate, or target bitrate) by using the
Check the ffmpeg docmentation for more information.
This is not compatible with the
opts = bitrate: '1200k'
.video() call returns an EventEmitter
to follow the progress of the conversion, since it can take a long time.
const emitter = downsizeemitter
Image/video resizing is hard to unit test. Instead, this repo contains an integration test suite made of many different resized files, covering different file formats and edge cases.
When submitting a change, make sure you run the build locally.
If you don't have all dependencies installed, you can also run the tests in Docker.
docker build -t downsize-test .