1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

アイコン探し

Posted at

アプリで使うアイコンを探したい

アプリ内で読み込みや保存とかに使うよくあるアイコン画像。
MS様とかがSDKで公開しているものとかは、数百以上ありファイル別のディレクトリに分かれているのですがこれを一個ずつ見ていくのは大変すぎる。
そこで、アイコン一覧を作るスクリプトを作ってみた。

使い方

  1. 以下のコマンドを実行
python icon_list.py /path/to/icon/dir
  1. /path/to/icon/dir/icons.htmlをブラウザで開く
    browser.png

ブラウザで出来る事

  • 閲覧している画像サイズをスライダで調整
  • 画像ファイル名でフィルタ(ありそうなファイル名を入れる。保存用アイコンだったらsave等)
  • 画像をクリックすると、クリップボードにその画像のファイルパスがコピーされる

一度icons.htmlを作ってしまえば、それ以降はブラウザで開くだけでお手軽です。

ファイル構成

場所は何処でも良いので、icon_list.pyとtemplate.htmlを同じディレクトリに置く

配置イメージ
./icon_list.py
./template.html

icon_list.py
import os
from pathlib import Path
import glob
import sys

def create_image_gallery_html(directory_path, output_file):
    """
    画像の一覧のhtmlを作成する
    :param directory_path: 画像のあるディレクトリパス
    :param output_file: 出力ファイル名(*.html)
    """
    # PNG画像ファイルを検索
    png_files = glob.glob(os.path.join(directory_path, "**/*.png"), recursive=True)
   
    # ギャラリーアイテムのHTML生成
    gallery_items = ""
    for image_path in png_files:
        relative_path = os.path.relpath(image_path, directory_path)
        filename = os.path.basename(image_path)
        gallery_items += f"""
            <div class="item">
                <div class="image">
                    <img src="{relative_path}" alt="{filename}" title="{relative_path}" loading="lazy">
                </div>
                <div class="caption">{filename}</div>
            </div>
        """
   
    # 最終的なHTMLの生成
    # HTMLテンプレートファイルを読み込んで全内容を取得
    with open("template.html", "r", encoding="utf-8") as file:
        html_template = file.read()  # ファイル全体を文字列として読み込む

    html_content = html_template.replace("{0}", gallery_items)
   
    # HTMLファイルの保存
    output_path = os.path.join(directory_path, output_file)
    with open(output_path, 'w', encoding='utf-8') as f:
        f.write(html_content)
   
    print(f"Gallery has been created at: {output_path}")
    return output_path

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python script.py <directory>")
        sys.exit(1)
    directory = sys.argv[1]
    output_html_file = 'icons.html'
    create_image_gallery_html(directory, output_html_file)
template.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Image Gallery</title>
	<style>
		body {
			margin: 0;
			padding: 20px;
			font-family: Arial, sans-serif;
		}
		.slider {
			position: fixed;
			top: 20px;
			right: 20px;
			background: rgba(255, 255, 255, 0.9);
			padding: 10px;
			border-radius: 5px;
			box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
			z-index: 1000;
			width: 200px;
		}
		.gallery {
			display: grid;
			grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
			gap: 20px;
			padding-top: 150px;
		}
		.item {
			width: 100%;
			background: #f5f5f5;
			padding: 10px;
			box-sizing: border-box;
			border-radius: 5px;
			display: flex;
			flex-direction: column;
			cursor: pointer;
			transition: background-color 0.2s;
		}
		.item:hover {
			background: #e0e0e0;
		}
		.item.copied {
			background: #d4f7d4;
		}
		.image {
			position: relative;
			width: 100%;
			padding-top: 75%; /* 4:3 aspect ratio */
			overflow: hidden;
		}
		.item img {
			position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
			object-fit: contain;
			object-position: center;
		}
		.caption {
			margin-top: 5px;
			font-size: 0.9em;
			text-align: center;
			word-break: break-all;
		}
		.filter {
			width: 100%;
			padding: 5px;
			margin-top: 10px;
			border: 1px solid #ccc;
			border-radius: 3px;
		}
		.hidden {
			display: none;
		}
		.copy-message {
			position: fixed;
			bottom: 20px;
			left: 50%;
			transform: translateX(-50%);
			background: rgba(0, 0, 0, 0.7);
			color: white;
			padding: 10px 20px;
			border-radius: 4px;
			opacity: 0;
			transition: opacity 0.3s;
			z-index: 1001;
		}
		.copy-message.show {
			opacity: 1;
		}
	</style>
</head>
<body>
<div class="slider">
	<label for="size-slider">画像サイズ調整:</label><br>
	<input type="range" id="size-slider" min="100" max="500" value="200">
	<br>
	<label for="filter-input">画像フィルター:</label><br>
	<input type="text" id="filter-input" class="filter-input" placeholder="画像名を入力...">
</div>
<div class="gallery" id="image-gallery">
{0}
</div>
<div class="copy-message" id="copy-message">URLをコピーしました</div>
<script>
    const slider = document.getElementById('size-slider');
    const gallery = document.getElementById('image-gallery');
    const filterInput = document.getElementById('filter-input');
    const copyMessage = document.getElementById('copy-message');

    slider.addEventListener('input', function () {
        const value = this.value;
        gallery.style.gridTemplateColumns = `repeat(auto-fill, minmax(${value}px, 1fr))`;
    });

    // フィルター機能の実装
    filterInput.addEventListener('input', function () {
        const filterValue = this.value.toLowerCase();
        const galleryItems = document.querySelectorAll('.item');
        galleryItems.forEach(item => {
            const img = item.querySelector('img');
            const altText = img.getAttribute('alt').toLowerCase();
            if (altText.includes(filterValue)) {
                item.classList.remove('hidden');
            } else {
                item.classList.add('hidden');
            }
        });
    });

    // クリップボードコピー機能
    function setupCopyFunction() {
        const items = document.querySelectorAll('.item');
        items.forEach(item => {
            item.addEventListener('click', function() {
                const img = this.querySelector('img');
                const imgSrc = img.getAttribute('src');

                // クリップボードにコピー
                navigator.clipboard.writeText(imgSrc)
                    .then(() => {
                        // コピー成功時の視覚的フィードバック
                        this.classList.add('copied');
                        setTimeout(() => {
                            this.classList.remove('copied');
                        }, 1000);

                        // コピーメッセージを表示
                        copyMessage.textContent = `${imgSrc} をコピーしました`;
                        copyMessage.classList.add('show');
                        setTimeout(() => {
                            copyMessage.classList.remove('show');
                        }, 2000);
                    })
                    .catch(err => {
                        console.error('クリップボードへのコピーに失敗しました:', err);
                        alert('クリップボードへのコピーに失敗しました。');
                    });
            });
        });
    }

    // 初期設定
    setupCopyFunction();

    function addNewGalleryItem(imageSrc, altText) {
        const newItem = document.createElement('div');
        newItem.className = 'item';

        newItem.innerHTML = `
            <div class="image">
                <img src="${imageSrc}" alt="${altText}" title="${imageSrc}" loading="lazy">
            </div>
            <div class="caption">${altText}</div>
        `;

        gallery.appendChild(newItem);

        setupCopyFunction();
    }
</script>
</body>
</html>
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?