出版日: 2023年12月30日
異なるサイズの多くの写真をコラージュに組み合わせたいと想像してください
この記事のタスクは、これらの写真を保持しながら、以下のようなコラージュに組み合わせることです。
以下のコードは、フォルダに含まれる画像ファイルをコラージュに変換します:
# 必要なライブラリをインポート
import os
from PIL import Image, ImageDraw
# 画像が含まれているフォルダを定義
directory = "./images"
# 画像のリストを取得
images = [i for i in os.listdir(directory) if i.endswith(".jpg") or i.endswith(".jpeg") or i.endswith(".png")]
# 出力コラージュのサイズとコラージュ内の1つの画像のサイズを (幅, 高さ) のタプルで定義
# 以下の値によって、横方向と縦方向にどれだけの画像が配置されるかが決まります
# 例: この場合 - 3600/600 = 6 および 1600/4 = 4 - コラージュは 6x4 になります
expected_size_collage = (3600, 1600)
expected_size_image = (600, 400)
# 画像を貼り付けるためのコラージュのキャンバスを作成
collage = Image.new("RGBA", expected_size_collage, color=(255,255,255,255))
# 画像ファイルをループする
file_count = 0
for h in range(0, expected_size_collage[1], expected_size_image[1]):
for w in range(0, expected_size_collage[0], expected_size_image[0]):
# 画像を読み込む
file_name = images[file_count]
path = directory + "/" + file_name
image = Image.open(path).convert("RGBA")
# 元の画像の幅と高さを取得
image_width = image.size[0]
image_height = image.size[1]
# 画像の幅と高さの調整方法を取得
width_factor = image_width / expected_size_image[0]
height_factor = image_height / expected_size_image[1]
# 幅と高さの調整係数が同じ場合、クロッピングは不要です
# そうでない場合は、画像を expected_size_image と同じ比率にクロップする必要があります
if width_factor != height_factor:
# 制限係数を取得
factor = min(width_factor, height_factor)
# 結果画像の幅と高さを計算
expected_width = round(factor * expected_size_image[0])
expected_height = round(factor * expected_size_image[1])
# 新しい画像の minx、miny、maxx、maxy 座標を取得
start_width = round((image_width - expected_width) / 2)
start_height = round((image_height - expected_height) / 2)
end_width = expected_width + round((image_width - expected_width) / 2)
end_height = expected_height + round((image_height - expected_height) / 2)
# 画像をクロップ
image = image.crop((start_width, start_height, end_width, end_height))
# 画像をクロップしたら、画像をリサイズします
# 画像は expected_size_image と同じアスペクト比を持っている必要があるため、リサイズは画像を妨げません
image = image.resize(expected_size_image)
# 画像をコラージュキャンバスに貼り付ける
collage.paste(image, (w, h))
file_count += 1
# コラージュを保存
collage.save("collage.png")
では、次にコードをステップバイステップで見てみましょう。
# 必要なライブラリをインポート
import os
from PIL import Image, ImageDraw
# 画像が含まれているフォルダを定義
directory = "./images"
# 画像のリストを取得
images = [i for i in os.listdir(directory) if i.endswith(".jpg") or i.endswith(".jpeg") or i.endswith(".png")]
# 出力コラージュのサイズとコラージュ内の1つの画像のサイズを (幅, 高さ) のタプルで定義
# 以下の値によって、横方向と縦方向にどれだけの画像が配置されるかが決まります
# 例: この場合 - 3600/600 = 6 および 1600/4 = 4 - コラージュは 6x4 になります
expected_size_collage = (3600, 1600)
expected_size_image = (600, 400)
# 画像を貼り付けるためのコラージュのキャンバスを作成
collage = Image.new("RGBA", expected_size_collage, color=(255,255,255,255))
上記のコードでは、PIL
を含む必要なライブラリをインポートします。これらのライブラリは、画像のクロッピングやリサイズに使用します。
指定されたフォルダ内で .png
.jpg
.jpeg
で終わる画像を収集し、リストに入れます。
次に、希望のコラージュのサイズを定義します。ここではフォルダに24枚の画像があり、6x4の画像をコラージュにしたいとします。
タイル(画像)は 600x400
のサイズが割り当てられ、これによりコラージュのサイズが
3600x1600
になります。次のセクションでは、このブランクキャンバスに画像タイルを貼り付けます。
# 画像ファイルをループする
file_count = 0
for h in range(0, expected_size_collage[1], expected_size_image[1]):
for w in range(0, expected_size_collage[0], expected_size_image[0]):
# 画像を読み込む
file_name = images[file_count]
path = directory + "/" + file_name
image = Image.open(path).convert("RGBA")
# 元の画像の幅と高さを取得
image_width = image.size[0]
image_height = image.size[1]
# 画像の幅と高さの調整方法を取得
width_factor = image_width / expected_size_image[0]
height_factor = image_height / expected_size_image[1]
# 幅と高さの調整係数が同じ場合、クロッピングは不要です
# そうでない場合は、画像を expected_size_image と同じ比率にクロップする必要があります
if width_factor != height_factor:
# 制限係数を取得
factor = min(width_factor, height_factor)
# 結果画像の幅と高さを計算
expected_width = round(factor * expected_size_image[0])
expected_height = round(factor * expected_size_image[1])
# 新しい画像の minx、miny、maxx、maxy 座標を取得
start_width = round((image_width - expected_width) / 2)
start_height = round((image_height - expected_height) / 2)
end_width = expected_width + round((image_width - expected_width) / 2)
end_height = expected_height + round((image_height - expected_height) / 2)
# 画像をクロップ
image = image.crop((start_width, start_height, end_width, end_height))
# 画像をクロップしたら、画像をリサイズします
# 画像は expected_size_image と同じアスペクト比を持っている必要があるため、リサイズは画像を妨げません
image = image.resize(expected_size_image)
# 画像をコラージュキャンバスに貼り付ける
collage.paste(image, (w, h))
file_count += 1
ここでは、2つのループを作成します。1つ目のループは画像を横に並べ、2つ目のループは行を移動します。たとえば、1つ目のループの最後には、以下のような画像があります:
ループ内では、以下の4つのアクションが実行されます:
600x400
の画像に変換しますか?
ここで、画像を 600x400
のアスペクト比に変換する必要があります。これを達成するために、実際のサイズを期待されるサイズで割って、実際の側がどのくらい大きいかを特定します。結果は
width_factor
と height_factor
変数に格納されます。次に、これら2つの比率のうち小さい方を使用して、この画像に合わせることができる
600x400
の最小倍数を特定します。
例えば、サイズが 2400x3000
の画像は、2400x1600
のサイズとして
600x400
のアスペクト比に合わせることができます。これは、垂直方向に 3000 - 1600 = 1400
ピクセルを削除する必要があることを意味します。ピクセルを削除するときは、画像の中央部分を残します。
画像がクロップされたら、すでに同じアスペクト比を持っているため、安全に 600x400
にリサイズできます。その後、タイル画像がコラージュキャンバスに貼り付けられます。
# コラージュを保存
collage.save("collage.png")
この最後のコードで、コラージュが指定された場所に保存されます。キャンバスが RGBA
画像として作成されたため、JPG
として保存することはできません。
このアルゴリズムのさらなる改善点としては、次のようなものがあります:
質問はありますか?コメントセクションでお知らせください。
このブログは英語からChatGPTによって翻訳されました。不明な点がある場合は、お問い合わせページからご連絡ください。
コメントを残す
コメント
Kash
8ヶ月前This is decent. But I want to go one step beyond this, and create a mixed collage with some landscape and some portrait images. To me, all landscape images look a bit bland. Mixed collage would be more dynamic. I've been trying to write code for this, but have been struggling for weeks. Dynamic image placement with some portraits and other landscape images is proving to be challenging. I'll get there.
その他のブログ
2024/06/19
SvelteとJavaScriptを使用してシンプルで動的なツールチップを作成する
2024/06/17
JavaScriptを用いて東京都のインタラクティブな地図を作成する
2024/06/14
Matplotlibで日本語文字化けを解決できる簡単な方法
2024/06/13
書評 | トーキング・トゥ・ストレンジャーズ 「よく知らない人」について私たちが知っておくべきこと by マルコム・グラッドウェル
2024/06/07
日本語で最もよく使われる3000字の漢字
2024/06/07
VSCodeでRegexを使用してReplaceする方法
2024/06/06
SvelteではReadable Storeを使用するな
2024/06/05
GzipとPakoでデータを圧縮してWebサイトのローディング速度を上げる方法
2024/05/31
JavaScriptを使用してWebページ上でマウスが指している単語を特定する
2024/05/29
SvelteとSVGを用いてインタラクティブな地図を作成する
2024/05/28
書評 | Originals 誰もが「人と違うこと」ができる時代 by アダム・グラント & シェリル・サンドバーグ
2024/05/27
Javascriptを使用して数独を解く方法
2024/05/26
ウェブサイトへのトラフィックを1か月で10倍に増やした方法
2024/05/24
人生はサイクリングに似ている
2024/05/19
JavaScriptでバックトラッキング・アルゴリズムを用いて完全な数独グリッドを生成する
2024/05/16
Tailwindが素晴らしい理由とWeb開発をいかに楽にするか
2024/05/15
PythonとGitフックを使用してサイトマップを自動的に生成する
2024/05/14
書評 | Range (レンジ) 知識の「幅」が最強の武器になる by デイビッド・エプスタイン
2024/05/13
SvelteとSvelteKitはなんですか?
2024/05/12
SvelteKitで国際化(多言語化)
2024/05/11
SvelteでCachingを用いてDeploy時間を短縮する方法
2024/05/10
SvelteとIntersection Oberverによるレイジーローディング
2024/05/10
遺伝的アルゴリズムで最適な株式ポートフォリオを作る方法
2024/05/09
Pythonを用いてShapeFileをSVGに変換できる方法
2024/05/08
Svelteの反応性:変数、バインディング、およびキー関数
2024/05/07
書評 | 孫子の兵法
2024/05/06
スペシャリストは終了。ゼネラリスト万歳!
2024/05/03
トルコ人の有権者の投票行動をPythonでの分析
2024/05/01
Seleniumを用いてトルコ投票データベースを作る方法
2024/04/30
SvelteとTailwindを使用してInfinite Scrollできる方法
2024/04/29
1年間以内で日本語を駆使できるようになるための方法
2024/04/25
SvelteとTailwindを用いたWebサイトテンプレート
2024/01/29
怠惰なエンジニアとひどいデザイン
2024/01/28
偉大さについて
2024/01/28
MacBook で PDF を PNG に変換する
2023/12/31
2023年振り返り:24冊の読んだ本のまとめ
2024/01/09
ウェブサイトの訪問者のデバイスとブラウザを検出する方法
2024/01/19
ChatGPT回答の解析