4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PythonでBMPファイルを出力する

Last updated at Posted at 2021-02-05

対象

いわゆる256bmpが対象です。
外部ライブラリは使っていません。
python3.9で動作確認しましたが、多少下のバージョンでも動くかもしれません。
対象読者は、どちらかというと、256bmpのフォーマットを知っており、他の言語で256bmpの読み書きを実装したことがある人です。
すぐ使えること、行数が少ないこと、ある程度読みやすいことを優先しています。堅牢さや多機能さの優先度は下げています。

経緯

256bmpのフォーマットはシンプルで、出力に必要な最低限の情報は、幅、高さ、パレット、画素の4つだけです。
ならば小物ツールを作るとき、install不要の標準ライブラリだけで楽に実装できそうです。

ということで参考情報を探すべく「python BMP 出力」等でぐぐったのですが、ドンピシャのものが見つからなかったため作りました。

なお、用途によっては画像系の外部ライブラリを使うことも多いでしょうし、あくまで参考になれば程度です。

サンプルコード

bmpWrite.py
#!/usr/bin/env python3.9
"""
bytearray to BMP
用途
  作成した画像データを、BMPファイルに保存する
使用方法
  colorTables と pixels を用意し、
  writeBmp() を呼び出す
"""

def writeBmp(filename, width, height, colorTables, pixels):
  with open(filename, 'wb') as f:
    lenOfColors = len(colorTables)
    numOfColors = lenOfColors >> 2
    lenOfPixels = len(pixels)
    bfOffBits = 14 + 0x28 + lenOfColors
    fileSize = bfOffBits + lenOfPixels

    #FILE_HEADER
    b = bytearray([0x42, 0x4d])               #シグネチャ 'BM'
    b.extend(fileSize.to_bytes(4, 'little'))  #ファイルサイズ
    b.extend((0).to_bytes(2, 'little'))       #予約領域
    b.extend((0).to_bytes(2, 'little'))       #予約領域
    b.extend(bfOffBits.to_bytes(4, 'little')) #ファイル先頭から画像データまでのオフセット[byte] ※誤った値だとアプリによっては表示失敗した

    #INFO_HEADER
    b.extend((0x28).to_bytes(4, 'little'))      #ヘッダーサイズ
    b.extend(width.to_bytes(4, 'little'))       #幅[dot]
    b.extend(height.to_bytes(4, 'little'))      #高さ[dot]
    b.extend((1).to_bytes(2, 'little'))         #プレーン数 常に1
    b.extend((8).to_bytes(2, 'little'))         #byte/1pixel(1byteを表すために必要なbit)
    b.extend((0).to_bytes(4, 'little'))         #圧縮形式 0 - BI_RGB(無圧縮)
    b.extend(lenOfPixels.to_bytes(4, 'little')) #画像データサイズ[byte]
    b.extend((0).to_bytes(4, 'little'))         #X方向解像度[dot/m] 0の場合もある
    b.extend((0).to_bytes(4, 'little'))         #Y方向解像度[dot/m] 0の場合もある
    b.extend(numOfColors.to_bytes(4, 'little')) #使用する色の数 ※0だとアプリによっては表示失敗した
    b.extend((0).to_bytes(4, 'little'))         #重要な色の数 0の場合もある

    #COLOR_TABLES
    b.extend(colorTables)

    #DATA
    b.extend(pixels)

    f.write(b)

# sample data
colorTables = [0x00, 0x00, 0xFF, 0x00,  0x00, 0xFF, 0x00, 0x00]  #Blue, Green, Red, Reserved, ...
pixels      = [0x00, 0x00, 0x01, 0x01,  0x00, 0x01, 0x00, 0x01]
writeBmp('sample.bmp', 4, 2, colorTables, pixels)

参考

Pythonでビットマップデータをバイナリレベルで作成する
Bitmapファイルフォーマット
BMP ファイルフォーマット

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?