ffmpegでサムネイル用画像を書き出す際、Node.jsのsharpと同じ拡縮指定となるように頑張ってみた。
sharpでは5種類(cover,contain,fill,inside,outside)の拡縮指定がある。
元画像
![](http://mztm.jp/wp/wp-content/uploads/2019/05/input.jpg)
cover
指定サイズを埋める最小の大きさに縦横比を維持して拡縮する。
1 |
ffmpeg.exe -i input.jpg -vf "scale=160:90:force_original_aspect_ratio=increase,crop=160:90" cover_160_90_output.jpg |
![]() cover 160×90 |
![]() cover 160×300 |
contain
指定サイズ内に収まるように縦横比を維持して拡縮する。余白は黒で塗りつぶし。
1 |
ffmpeg.exe -i input.jpg -vf "scale=160:90:force_original_aspect_ratio=decrease,pad=160:90:(ow-iw)/2:(oh-ih)/2" contain_160_90_output.jpg |
![]() contain 160×90 |
![]() contain 160×300 |
fill
指定サイズを埋めるように拡縮する。
1 |
ffmpeg.exe -i input.jpg -vf "scale=160:90" fill_160_90_output.jpg |
![]() fill 160×90 |
![]() fill 160×300 |
inside
指定サイズの箱の内側にハマる最大サイズで縦横比を維持して拡縮する。
1 |
ffmpeg.exe -i input.jpg -vf "scale='if(lt(160/iw, 90/ih),160,-1)':'if(lt(160/iw, 90/ih),-1,90)'" inside_160_90_output.jpg |
![]() inside 68×90 |
![]() inside 160×213 |
outside
指定サイズの箱の外側にハマる最小サイズで縦横比を維持して拡縮する。
1 |
ffmpeg.exe -i input.jpg -vf "scale='if(gt(160/iw, 90/ih),160,-1)':'if(gt(160/iw, 90/ih),-1,90)'" outside_160_90_output.jpg |
![]() outside 160×213 |
![]() outside 225×300 |
node.jsのコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
setimg('cover', 160, 90); setimg('contain', 160, 90); setimg('fill', 160, 90); setimg('inside', 160, 90); setimg('outside', 160, 90); function setimg(fit, w, h) { w = w || -1; h = h || -1; var AppPath = 'D:\\inetpub\\ffmpeg-20180820-78d4b6b-win64-static\\bin\\ffmpeg.exe'; var scale; if (fit == 'cover') { scale = ' -vf "scale=' + w + ':' + h + ':force_original_aspect_ratio=increase,crop=' + w + ':' + h + '"'; } else if (fit == 'contain') { scale = ' -vf "scale=' + w + ':' + h + ':force_original_aspect_ratio=decrease,pad=' + w + ':' + h + ':(ow-iw)/2:(oh-ih)/2"'; } else if (fit == 'fill') { scale = ' -vf "scale=' + w + ':' + h + '"'; } else if (fit == 'inside') { scale = ' -vf "scale=\'if(lt(' + w + '/iw, ' + h + '/ih),' + w + ',-1)\':\'if(lt(' + w + '/iw, ' + h + '/ih),-1,' + h + ')\'"'; } else if (fit == 'outside') { scale = ' -vf "scale=\'if(gt(' + w + '/iw, ' + h + '/ih),' + w + ',-1)\':\'if(gt(' + w + '/iw, ' + h + '/ih),-1,' + h + ')\'"'; } var cmd = AppPath + ' -i input.jpg' + scale + ' ' + fit + '_' + w + '_' + h + '_output.jpg'; console.log(cmd); require('child_process').exec(cmd, (err, stdout, stderr) => { console.log('err:', err); console.log('stdout:', stdout); console.log('stderr:', stderr); }); } |
参考
Scaling – FFmpeg
Documentation
Resizing images – sharp
Node.jsのライブラリsharpでリサイズを試してみる | Simple is Beautiful.