アイデア
プログラマーの脳は、プログラミングなしでは存在できません。 ルーチン操作を3回以上繰り返す必要があるタスクは、「これをどのように自動化するのか」という疑問をすぐに頭に浮かび始めます。 それで、今回は起こりました。
少し「頭をかく」と言った後、 焦点の概念を導入し、切り取るときにそれを考慮する必要があるという結論に達しました。 たとえば、新しい画像の縦横比が元の画像の縦横比に近い場合、アスペクト比が3から4の四角形を四角形から切り取ると、すべてが正常になり、新しい画像の構図が失われることはありません。 新しい画像のサイズが非常に異なる場合、たとえば、スライダーの幅が狭い場合は、少なくとも最も重要な情報を保存します。 忘れないでください、我々はまだ自動トリミングについて話している。
これがメカニズムを示す図です。
したがって、 焦点とは、画像の最も重要な部分を含む領域の中心の点であり、切り取られたときにとにかく残る必要があります。 通常の写真撮影では、レンズは撮影中にこの領域に焦点を合わせます。これは、撮影が浅い被写界深度で行われた場合に特に明確です。 したがって、実際には、コンセプトの名前。
私は結論を確認し、誰かがすでに似たようなことをしているかどうかを調べることにしました。 github.com/adamdbradley/focal-pointでアダプティブ画像をトリミングするためのHTML / CSSライブラリが見つかりました。 ここでは、「フォーカスポイント」の概念も使用されます。これは、私の考えが正しいことを意味します。 しかし、物理的な画像を生成できる既製のユーティリティが必要でした。 これが見つかりませんでした。
実装
それからNode.jsを使いました。Node.jsは永続的な作業ツールではありませんが、自動化と小さなユーティリティに使用したいものです。
新しい画像のトリミングアルゴリズムは次のとおりです。
- 最終画像の比率を計算します。
k=Wr/Hr
、
ここで、WrとHrは、将来の画像の幅と高さです。 - 元の画像に収まる最大の長方形を決定します。
if Wr >= Hr
then Wm = Wi, Hm = Wi/k
else Hm = Hi, Wm = Hm*k
、
ここで、Wi、Hiは元の寸法、Wm、Hmは最大の長方形の寸法です。
- 焦点の新しい座標を計算します。
fx2 = fx*Wm/Wi
、
fy2 = fy*Hm/Hi
、
fx、fx-元の画像の焦点の座標
- 焦点の古い座標と新しい座標の差によって長方形をシフトすることにより、実際のトリミングを行います。
crop(Wm, Hm, (fx-fx2), (fy-fy2))
- 結果を目的のサイズに縮小します。
resize(Wr, Hr)
画像処理については、 ノードモジュール用のGraphicsMagickを使用しました。これは、Windowsのグラフィックライブラリとシームレスに連携することが約束されているためです。 そして、ほとんど嘘をつきませんでした。 ImageMagickと一緒に起動することはできませんでした(そして、古いimagemagick-nodeモジュールは問題なく動作しました)が、GraphicsMagickの形式の代替はすぐに機能し、シャーマニズムもありませんでした。 理論的には、ImageMagickは別のプラットフォームでも動作するはずです。gmモジュールにはライブラリへのハードリンクはありません。
最後のユーティリティでは、Web用に少し最適化を追加しました。すべてのEXIF、ICMなどが最終画像から切り取られ、情報と結果の小さな画像がシャープネスフィルターで実行されます。 3000x4000pxから200x300pxに減らす場合、これは本当に必要です。
便宜上、ソースデータは2つのファイルの形式で受け入れられます。
- format.json-トリミングするフォーマットをリストするファイル
- images.json-画像をリストし、フォーカスポイントを設定するファイル。 ここで、画像を保存する場所と品質を指定できます。
GitHub github.com/fetis/fcropのリポジトリで、ファイル形式、インストール、および追加機能について詳しく読むことができます。 ここで、例のデモを見つけることができます。
そして最後に、ユーティリティの例
元の画像へのリンク5.4 Mb
200x135
500x180
900x172