【保存版】Windowsのmoricons.dllからすべてのアイコンを抽出するPythonスクリプトを解説【PNG保存】

2025-05-27 Edit on Windows

Pythonmoricons.dll内のすべてのアイコンを抽出し、PNG形式で保存する完全ガイド。Windows APIとPillowを活用し、化けずにきれいな画像が出力されます!

✅ このブログで解決できること

🔍 moricons.dllとは?

moricons.dll は、Windows に古くから存在する クラシックアプリ向けのアイコンリソースDLL です。

Windows 3.1時代の懐かしのアイコンが多く格納されています。

moricons.dllのアイコン一覧

保存場所:

C:\Windows\System32\moricons.dll

🐍 PythonだけでDLL内アイコンをPNGに変換する方法

必要なライブラリ

pip install pywin32 pillow

🧠 完全動作するPythonコード

# Pythonコード(コピーして使用可能)
import ctypes
import ctypes.wintypes as wintypes
import win32gui
import win32ui
import win32con
import os
from PIL import Image
import struct


gdi32 = ctypes.WinDLL("gdi32")

class BITMAP(ctypes.Structure):
    _fields_ = [
        ('bmType', ctypes.c_long),
        ('bmWidth', ctypes.c_long),
        ('bmHeight', ctypes.c_long),
        ('bmWidthBytes', ctypes.c_long),
        ('bmPlanes', ctypes.c_ushort),
        ('bmBitsPixel', ctypes.c_ushort),
        ('bmBits', ctypes.c_void_p),
    ]

def get_bitmap_bits(hdc, hbmp):

    bmp = BITMAP()
    hbm_handle = ctypes.c_void_p(int(hbmp)) 
    gdi32.GetObjectW(hbm_handle, ctypes.sizeof(bmp), ctypes.byref(bmp))

    width = bmp.bmWidth
    height = bmp.bmHeight
    bits_per_pixel = bmp.bmBitsPixel

    class BITMAPINFOHEADER(ctypes.Structure):
        _fields_ = [
            ('biSize', ctypes.c_uint32),
            ('biWidth', ctypes.c_int32),
            ('biHeight', ctypes.c_int32),
            ('biPlanes', ctypes.c_uint16),
            ('biBitCount', ctypes.c_uint16),
            ('biCompression', ctypes.c_uint32),
            ('biSizeImage', ctypes.c_uint32),
            ('biXPelsPerMeter', ctypes.c_int32),
            ('biYPelsPerMeter', ctypes.c_int32),
            ('biClrUsed', ctypes.c_uint32),
            ('biClrImportant', ctypes.c_uint32)
        ]

    class BITMAPINFO(ctypes.Structure):
        _fields_ = [
            ('bmiHeader', BITMAPINFOHEADER),
            ('bmiColors', ctypes.c_uint32 * 3)
        ]

    bmi = BITMAPINFO()
    bmi.bmiHeader.biSize = ctypes.sizeof(BITMAPINFOHEADER)
    bmi.bmiHeader.biWidth = width
    bmi.bmiHeader.biHeight = -height  # 上下反転を防ぐ
    bmi.bmiHeader.biPlanes = 1
    bmi.bmiHeader.biBitCount = 24
    bmi.bmiHeader.biCompression = 0  # BI_RGB

    row_bytes = ((width * 3 + 3) // 4) * 4
    size = row_bytes * height
    buffer = ctypes.create_string_buffer(size)

    res = gdi32.GetDIBits(
        ctypes.c_void_p(int(hdc)),
        ctypes.c_void_p(int(hbmp)),
        0, height,
        buffer,
        ctypes.byref(bmi),
        0  # DIB_RGB_COLORS
    )

    if res == 0:
        raise ctypes.WinError()

    return buffer.raw, width, height

def save_icon_as_png(icon_handle, index):
    hdc = win32gui.GetDC(None)
    hdc_mem = win32gui.CreateCompatibleDC(hdc)
    hbm = win32gui.CreateCompatibleBitmap(hdc, 32, 32)
    win32gui.SelectObject(hdc_mem, hbm)
    win32gui.DrawIconEx(hdc_mem, 0, 0, icon_handle, 32, 32, 0, 0, win32con.DI_NORMAL)
    bmp_data, width, height = get_bitmap_bits(hdc_mem,hbm)

    image = Image.frombuffer("RGB", (width, height), bmp_data, "raw", "BGR", 0, 1)
    image = image.transpose(Image.FLIP_TOP_BOTTOM)
    os.makedirs("icons", exist_ok=True)
    image.save(f"icons/icon_{index}.png")

    win32gui.DeleteObject(hbm)
    win32gui.DeleteDC(hdc_mem)
    win32gui.ReleaseDC(0, hdc)

def extract_all_icons_from_dll(dll_path):
    large, small = win32gui.ExtractIconEx(dll_path, 0, 100)
    for i, icon in enumerate(large):
        save_icon_as_png(icon, i)

extract_all_icons_from_dll(r"C:\Windows\System32\moricons.dll")

🧪 実行方法

ファイル名を extract_icons.py として保存し、以下で実行します:

python extract_icons.py

📂 出力されるファイル

以下のように自動で保存されます:

icons/icon_0.png
icons/icon_1.png
icons/icon_2.png
...
  

🎯 用途アイデア

🚀 まとめ

目的moricons.dllのアイコンをPNGに抽出
使用言語Python 3
ライブラリpywin32、Pillow
出力形式PNG(32×32)
対象OSWindows 10 / 11

Pythonのデコレータ(@記号)を初心者向けに解説!

pygameの機能とインストール方法

PythonでTOTP・HOTPを実装する方法|ワンタイムパスワード

Python ブラウザ指定し自動で開く!webbrowserモジュール完全ガイド

Pythonでmoricons.dllのアイコンをPNGとして抽出する方法