見出し画像

写真にいい感じに枠をつけてインスタ映えさせるアプリを作ってみた

初投稿です。
はじめまして。たぱすたぱすたと申します。
名前はそこまで気に入ってないので、いいの思いついたら後で変えます。

今回はPythonの環境構築できてる人向けの記事になります。

前置き

大学院で画像系の研究をしていたのですが、就職してから院で学んだ知識を発揮する場面もなく……というわけで、忘れる前になんとか形にして残しておかなきゃ!なんて使命感に日々駆られております。

話は変わりますが、ちょっと前にInstagramを始めました。
写真が趣味なので撮影した写真を投稿することもあるのですが、1つ不満があります。正方形しか上げられないことです。正確には正方形でなくてもいいのですが、違うアスペクト比の写真を上げようとすると、一方のアス比に合わせられ、写真の一部が切り取られてしまいます。

名称未設定のアートワーク

ある日Instagramでこんな写真を見つけました。

画像8

※当時の再現です。

なんかおしゃれやん!
調べてみたらどうやら白枠をつけるアプリがあるみたいです。
ですがPhotoshopやLightroomで編集する身としては、スマホアプリで加工を挟むのは結構面倒です。

そこで、Pythonでいい感じに画像に枠をつけるアプリケーションを作成しました。(アプリといってもコマンドラインベースです)

原理

まずはシンプルな例を考えてみます。

図1

元の画像に対して大きい下地を作ってあげて、そこに写真を配置してあげればOKです。
どのくらいの大きさの下地を作るかですが、ここは黄金比を使います。(よりよいものがあれば教えてください)

参考:ウィキペディア
https://ja.wikipedia.org/wiki/%E9%BB%84%E9%87%91%E6%AF%94


しかし、この計算式では縦長画像や横長画像に対応することができませんね。そこで横長の場合を考えてみましょう。

図2

下地は短辺を黄金比倍したものの正方形にします。
高さの黄金比倍が幅より大きければ、この式が成り立ちます。

縦長画像の場合は画像読み込み時に転置してしまえば別に式を作ることなく適用できますね。

実装

GitHubにコードを上げているのでぜひ使用してみてください。

new_width = int(self.height * 1.618)
new_img = numpy.ones([new_width, new_width, self.color], dtype="float64")

黄金比に基づいて、新しい画像のサイズを計算します。
このサイズの正方形の画像が基本のレイヤーとなり、その上に既存の写真を置いていきます。

# 画像を枠の中に配置する起点の計算
if self.isSquare:
   sh = int(self.height*0.309)
   sw = int(self.width*0.309)
else:
   sh = int(self.height*0.309)
   sw = int((1.618*self.height-self.width)//2)

new_img[sh:sh+self.height, sw:sw+self.width] = self.img

return (new_img * 255).astype(numpy.int)

元画像が正方形の場合とそれ以外の場合で計算式を分けています。
画像の代入はスライスを使用するとスマートになりますね。

最後は正規化した値を8bitに直して完成です。
※輝度をいじらない場合は正規化しなくても大丈夫です。

使用例

では、作成したプログラムを実行してみます。

python main.py inputpath outputpath -g

画像のサイズが大きいと処理に時間がかかることがあります。
写真の解像度を落とさないように、元画像の約1.6倍の大きさの画像になるので、出力画像もなかなか大きいものになります。

できたファイルがこちらです。BeforeAfterでどうぞ。
※写真の無断利用はご遠慮ください。

画像1

画像2

画像3

画像4

noteの白背景だと違いが分かりにくいですかね。
instagramだと写真の雰囲気が変わるのでぜひ試してみてください。

おわりに

今回はインスタ映えするアプリを作ってその解説をしてみました。

こんな感じで不定期で技術的な記事を上げていこうと考えています。
また、趣味に関する話もできたらいいなと思っています。

それでは次回の記事でもよろしくお願いします。

この記事が気に入ったらサポートをしてみませんか?