Convert / resize / transcode photos & videos to be web-friendly
npm install thumbsup-downsize> Convert / resize / transcode / down-sample photos & videos to be web-friendly
This is one of the core modules of thumbsup.github.io.


!Tests
!Dependencies

``bash`
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
- ExifTool
`js
const downsize = require('thumbsup-downsize')
const options = { height: 100, width: 100 }
downsize.image('source.tiff', 'thumb.jpg', options, (err) => {
console.log(err || 'Thumbnail created successfully')
})
`
`js`
.image(source, target, options, callback)
Processes the image in source and creates a new image in target.target
The image is appropriately converted if needed based on the file extension.
You can specify the following options:
##### Image size
`js
// proportionally resize the photo to a maximum height
opts = { height: 300 }
// proportionally resize the photo to a maximum width
opts = { width: 300 }
// resize and crop the photo to exactly height x width
// the image will not be distorted
opts = { height: 100, width: 100 }
`
##### Image quality
`js`
// quality between 0 and 100
opts = { quality: 80 }
##### Preserving metadata
By default, all metadata is removed from downsized images.
This option will keep all EXIF / IPTC / XMP metadata in the target files.
When setting this option to true, images will no longer be auto-rotated.
`js`
opts = { keepMetadata: true }
##### Watermark
You can overlay a transparent watermark over the final image:
`js`
opts = {
watermark: {
file: 'path/watermark.png', // transparent PNG
position: 'NorthEast' // position of the watermark
}
}
The possible values for position are:
- Repeat to repeat the watermark across the whole imageCenter
- to position the watermark in the middleNorthWest
- , North, NorthEast, West, East, SouthWest, South, SouthEast to position the watermark along the edge
Note: watermarks are not compatible with cropped images.
The watermark option will simply be ignored if both width and height are specified.
##### Post-processing
You can specify extra arguments that will be passed to GraphicsMagick.
This only works with output arguments.
`js`
opts = {
args: [
'-unsharp 2 0.5 0.7 0',
'-modulate 120'
]
}
##### GIF animation
By default, only the first frame of an animated GIF is exported.
You can keep the entire animation by specifying:
`js`
opts = { animated: true }
This offloads the processing of the image to Gifsicle.
Note that:
- The destination file extension must be .gifwidth
- The only other supported parameters are and 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.
`js`
.still(source, target, options, callback)
Extract a single frame from the video in source, and writes the image to target..image()
This method supports all the same options as , with the addition of:
`js`
opts = {
// take the screenshot at the very start of the video
seek: 0
// take the screenshot after N second (default = 1)
seek: 1
// take the screenshot in the middle of the video
seek: -1
}
If seeking fails for any reason, the first frame is used instead.
`js`
.video(source, target, options, callback)
Transcodes the video in source to a web-friendly format and lower bitrate, and writes it in target.
You can specify the following options:
##### Format
The default export format is mp4.format
You can specify an export format by adding a option:
`js`
opts = { format: 'mp4' } // H264 encoder
opts = { format: 'webm' } // VP9 encoder
Note: encoding as webm is much slower.
##### Video quality
The default behaviour is to use CRF (constant rate factor) to control the output quality.
The default value is 75%.
`js`
// value between 0 (worst) and 100 (best)
opts = { quality: 75 }
Notes:
- 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
##### Variable bitrate
Instead of CRF, you can specify a variable bitrate (a.k.a. average bitrate, or target bitrate) by using the bitrate option.quality
Check the ffmpeg docmentation for more information.
This is not compatible with the option.
`js`
opts = { bitrate: '1200k' }
##### HW acceleration
Enable VAAPI HW acceleration if supported on your platform (typically Intel/AMD chipsets).
Requires intel-media-driver package to enable.
This is not compatiable with the quality option and requires a bitrate setting.none
The default value is .
`js`
// values 'vaapi' or 'none'
opts = { hwaccel: 'vaapi' }
##### Video FPS
The default export video FPS is 25. You can specify an explicit FPS by adding a framerate option:
`js`
opts = { framerate: 60 }
opts = { framerate: 0 } // preserve the original source video's FPS
##### Preserving Metadata
By default, all metadata is removed from the target video.
This option preserves the metadata.
`js`
opts = { keepMetadata: true }
##### Conversion progress
The .video() call returns an EventEmitter
to follow the progress of the conversion, since it can take a long time.
`js${percent}%
const emitter = downsize.video(/ ... /)
emitter.on('progress', percent => console.log())`
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.
`bash`
npm test
If you don't have all dependencies installed, you can also run the tests in Docker.
`bash``
docker build -t downsize-test .