BMPファイル、DIBのアルファ値について
2026-06-29時点での記事
MSDN内でも記載が揺れてたりで、ぐちゃぐちゃになった頭を整理する意図も込めて、単一記事にします。
変なこと言ってたら、指摘してください。
結論
BITMAPINFOHEADERのBI_RGB + 32bppの組み合わせでは、第4バイト(上位バイト)はアルファ値として正式に定義されておらず、「未使用(reserved)」と規定されている。
そのため、どう解釈するかはソフトによりけりである。
解説
BMPファイルのそもそもの構造について
そもそもBMPファイルは以下のような構造になっています。詳しく読まなくても下で簡潔にまとめています。
ビットマップは、確立されたビットマップ ファイル形式を使用したファイルに保存し、ファイルの名前に 3 文字の .bmp 拡張子を付ける必要があります。 確立されたビットマップ ファイル形式は、BITMAPFILEHEADER 構造体と、それに続く BITMAPINFOHEADER、BITMAPV4HEADER、または BITMAPV5HEADER 構造体で構成されます。 ビットマップ情報ヘッダー構造の後に、RGBQUAD 構造体の配列 (カラー テーブルとも呼ばれます) が続きます。 カラー テーブルの後には、カラー テーブルに対するインデックスが格納される 2 番目の配列 (実際のビットマップ データ) が続きます。
より(2026-06-29閲覧)
BITMAPV5HEADER 構造体は拡張 BITMAPV4HEADER 構造体であり、拡張 BITMAPINFOHEADER 構造体です。 ただし、BITMAPINFOHEADER および BITMAPCOREHEADER には、他のビットマップ ヘッダー構造体と共通の Size メンバーしかありません。
BITMAPCOREHEADER および BITMAPV4HEADER 形式は、それぞれ BITMAPINFOHEADER および BITMAPV5HEADER 形式に置き換えられます。 完全性と下位互換性のために BITMAPCOREHEADER および BITMAPV4HEADER 形式が表示されます。
DIB の形式は次のとおりです (詳細については、「ビットマップ ストレージ」を参照してください)。
BITMAPFILEHEADER 構造体
BITMAPCOREHEADER、BITMAPINFOHEADER、BITMAPV4HEADER、または BITMAPV5HEADER 構造体のいずれか。
オプションのカラー テーブル。これは、RGBQUAD 構造体のセット、または一連の RGBTRIPLE 構造体です。
ビットマップ データ
省略可能なプロファイル データ
より(2026-06-29閲覧)
つまり、現在の推奨では
table:structure
BITMAPFILEHEADER
BITMAPINFOHEADER or BITMAPV5HEADER
RGBQUAD
実データ
という構造になっています。
実は、BITMAPV5HEADERはあまり使われていません...詳細については後述します。
よって、現在の主流はBITMAPFILEHEADER + BITMAPINFOHEADER + RGBQUAD + 実データです。
この構成からBITMAPFILEHEADERを抜いたものを一般的に「DIB (Device Independent Bitmap)」と言います。
RGBAを保持したい場合のビットマップ構造について
BMPファイル(ビットマップファイル)でアルファ値がある場合、内部構造でBMPINFOHEADERは以下のようになっていることが多いです。
code:toml
biCompression = BI_RGB
biBitCount = 32
この場合、1ピクセル当たり32bitが使用されるが、公式の仕様ではBGRの順で使用され、最上位ビットは未使用とされています。つまり、BGRAではなくBGRXの構成です。
ビットマップ配列の各 DWORD は、ピクセルの青、緑、赤の相対的な強度を表します。 各 DWORD の上位バイトは使用されません。
より(2026-06-29閲覧)
そのため、どう解釈するかはソフトによりけりです。
ーーーーーーーーーーーー
あとは余談です。
BITMAPV5HEADERについて
実は、BITMAPV5HEADERではアルファを扱えるっぽいです!なんで移行しないの?
これは推測も含むのですが、
bV5AlphaMaskというフィールドがあるものの...
https://learn.microsoft.com/ja-jp/windows/win32/api/wingdi/ns-wingdi-bitmapv5header
他のマスク系のフィールドは有効タイミングが書いてありますが...により、解釈ミスで実装ばらけそう?
BI_RGBでも扱う?
BITMAPINFOHEADERで十分みたいな移行の渋り
互換性問題
Microsoft Wordですら、BITMAPV5HEADERに関するバグがあったようで、PNGを利用する方向に全体的に動いていた...?
後述のクリップボードデータ取得を見てみると、MicrosoftのソフトはBITMAPV5を登録しないようです?
とかありそうです。
クリップボードデータを調べてみる
このページの末尾のPowerShellのコードは、クリップボードのデータを取得して、どんなタイプのものがあるかのリストを取得するものです。
簡易版スクリプトで、各種ペイントツールなどでコピーしたデータを取得してみると以下のような出力になりました。
DeviceIndependentBitmapってのが通常のBMPだと思っていいです。
で、Format17がBITMAPV5 ( CF_DIBV5 ) なんですが、MSのソフトは登録していませんね!意図的かはわかりませんが。その代わりにPNGやファイル自体が登録されているようです。
※記載されている中には実データがないものも含まれているので、必ず要求したデータが取得できるとは限らないです。
code:ペイント 11.2603.251.0.txt
Embed Source
Object Descriptor
MetaFilePict
DeviceIndependentBitmap
PNG
image/png
code:フォト 右クリコピー.txt
Preferred DropEffect
HTML Format
System.Drawing.Bitmap
Bitmap
Shell IDList Array
FileDrop
FileNameW
FileName
FileContents
FileGroupDescriptorW
code:Krita 5.3.2.1.txt
Format17
DeviceIndependentBitmap
application/zip
application/x-krita-node-internal-pointer
image/png
image/bmp
image/bw
image/cur
image/icns
image/ico
image/jpeg
image/jpg
image/pbm
image/pcx
image/pgm
image/pic
image/ppm
image/rgb
image/rgba
image/sgi
image/tga
image/tif
image/tiff
image/wbmp
image/webp
image/xbm
image/xpm
code:GIMP 3.2.4.txt
image/x-xcf
image/png
PNG
image/avif
image/bmp
DeviceIndependentBitmap
image/x-bmp
image/x-MS-bmp
image/x-icon
image/x-ico
image/x-win-bitmap
image/vnd.microsoft.icon
application/ico
image/ico
image/icon
text/ico
image/jxl
image/tiff
image/jpeg
JFIF
System.Drawing.Bitmap
Bitmap
Format17
code:Chrome jpg/png.txt
PNG
Format17
HTML Format
UniformResourceLocatorW
Chromium internal source RFH token
Chromium internal source URL
System.Drawing.Bitmap
Bitmap
DeviceIndependentBitmap
code:無印AviUtl.txt
DeviceIndependentBitmap
System.Drawing.Bitmap
Bitmap
Format17
code:AviUtl ExEdit2.txt
DeviceIndependentBitmap
System.Drawing.Bitmap
Bitmap
Format17
クリップボードのデータ取得コード
Claude Sonnet 4.6さん。ありがとう。ちょいと修正してます。
簡易版
code:pwsh
Add-Type -AssemblyName System.Windows.Forms
function Get-ClipboardFormats {
$clipboard = System.Windows.Forms.Clipboard::GetDataObject()
$clipboard.GetFormats()
}
# 実行
Get-ClipboardFormats
詳細版
code:pwsh
Add-Type -AssemblyName System.Windows.Forms
function Get-ClipboardFormatDetails {
$clipboard = System.Windows.Forms.Clipboard::GetDataObject()
foreach ($format in $clipboard.GetFormats()) {
Write-Host "=== Format: $format ===" -ForegroundColor Cyan
try {
$data = $clipboard.GetData($format)
Write-Host $data
} catch {
Write-Host "(取得不可)" -ForegroundColor Yellow
}
}
}
# 実行
Get-ClipboardFormatDetails
BITMAPの詳細出力版
code:ps1
Add-Type -AssemblyName System.Windows.Forms
function Get-DIBFromClipboard {
$dataObj = System.Windows.Forms.Clipboard::GetDataObject()
# CF_DIB (フォーマット8) を取得
$hasDIB = $dataObj.GetDataPresent("DeviceIndependentBitmap")
$hasDIBV5 = $dataObj.GetDataPresent("Format17") # CF_DIBV5
if (-not $hasDIB -and -not $hasDIBV5) {
Write-Host "クリップボードにDIBデータがありません。" -ForegroundColor Red
return
}
# バイト列として取得
$format = if ($hasDIBV5) { "Format17" } else { "DeviceIndependentBitmap" }
$stream = $dataObj.GetData($format)
if ($stream -is System.IO.Stream) {
$bytes = New-Object byte[] $stream.Length
$stream.Read($bytes, 0, $bytes.Length) | Out-Null
} elseif ($stream -is [byte[]]) {
$bytes = $stream
} else {
Write-Host "データを byte[] に変換できません: $($stream.GetType().FullName)" -ForegroundColor Red
return
}
Write-Host "`n=== DIBデータ解析 ===" -ForegroundColor Cyan
Write-Host "総バイト数 : $($bytes.Length) bytes"
Write-Host "フォーマット: $(if ($hasDIBV5) { 'CF_DIBV5 (17)' } else { 'CF_DIB (8)' })"
# --- BITMAPINFOHEADER を解析 ---
# CF_DIB はファイルヘッダなし、先頭が BITMAPINFOHEADER
$biSize = BitConverter::ToInt32($bytes, 0)
$biWidth = BitConverter::ToInt32($bytes, 4)
$biHeight = BitConverter::ToInt32($bytes, 8) # 負なら Top-Down
$biPlanes = BitConverter::ToInt16($bytes, 12)
$biBitCount = BitConverter::ToInt16($bytes, 14)
$biCompression = BitConverter::ToUInt32($bytes, 16)
$biSizeImage = BitConverter::ToUInt32($bytes, 20)
$biXPPM = BitConverter::ToInt32($bytes, 24)
$biYPPM = BitConverter::ToInt32($bytes, 28)
$biClrUsed = BitConverter::ToUInt32($bytes, 32)
$biClrImportant= BitConverter::ToUInt32($bytes, 36)
# 圧縮方式の名前変換
$compressionName = switch ($biCompression) {
0 { "BI_RGB (無圧縮)" }
1 { "BI_RLE8" }
2 { "BI_RLE4" }
3 { "BI_BITFIELDS" }
4 { "BI_JPEG" }
5 { "BI_PNG" }
default { "不明 ($_)" }
}
# 解像度の DPI 換算 (1インチ = 0.0254m)
$dpiX = math::Round($biXPPM * 0.0254, 1)
$dpiY = math::Round($biYPPM * 0.0254, 1)
# 行ストライドと理論サイズ
$absHeight = math::Abs($biHeight)
$stride = math::Floor(($biWidth * $biBitCount + 31) / 32) * 4
$pixelSize = $stride * $absHeight
Write-Host "`n--- BITMAPINFOHEADER ($biSize bytes) ---" -ForegroundColor Yellow
Write-Host (" biSize : {0} bytes (ヘッダ種別: {1})" -f $biSize, $(
switch ($biSize) {
12 { "BITMAPCOREHEADER" }
40 { "BITMAPINFOHEADER" }
52 { "BITMAPV2INFOHEADER" }
56 { "BITMAPV3INFOHEADER" }
108 { "BITMAPV4HEADER" }
124 { "BITMAPV5HEADER" }
default { "不明" }
}))
Write-Host (" biWidth : {0} px" -f $biWidth)
Write-Host (" biHeight : {0} px ({1})" -f $biHeight, $(if ($biHeight -lt 0) { "Top-Down" } else { "Bottom-Up (標準)" }))
Write-Host (" biPlanes : {0}" -f $biPlanes)
Write-Host (" biBitCount : {0} bpp ({1})" -f $biBitCount, $(
switch ($biBitCount) {
1 { "モノクロ" }; 4 { "16色" }; 8 { "256色" }
16 { "ハイカラー" }; 24 { "フルカラー" }; 32 { "32bit ARGB" }
default { "不明" }
}))
Write-Host (" biCompression : {0}" -f $compressionName)
Write-Host (" biSizeImage : {0} bytes" -f $biSizeImage)
Write-Host (" 解像度 : {0} x {1} pixels/m ({2} x {3} DPI)" -f $biXPPM, $biYPPM, $dpiX, $dpiY)
Write-Host (" biClrUsed : {0} (0=フルカラー)" -f $biClrUsed)
Write-Host (" biClrImportant: {0}" -f $biClrImportant)
Write-Host "`n--- 計算値 ---" -ForegroundColor Yellow
Write-Host (" 行ストライド : {0} bytes (= (({1} × {2} + 31) / 32) × 4)" -f $stride, $biWidth, $biBitCount)
Write-Host (" ピクセル領域 : {0} bytes (stride × 高さ)" -f $pixelSize)
# カラーテーブル
if ($biBitCount -le 8) {
$clrCount = if ($biClrUsed -gt 0) { $biClrUsed } else { math::Pow(2, $biBitCount) }
Write-Host "`n--- カラーテーブル ($clrCount 色) ---" -ForegroundColor Yellow
$ctOffset = $biSize
$showMax = math::Min($clrCount, 16)
for ($i = 0; $i -lt $showMax; $i++) {
$b = $bytes$ctOffset + $i * 4
$g = $bytes$ctOffset + $i * 4 + 1
$r = $bytes$ctOffset + $i * 4 + 2
Write-Host (" {0,3} R={1,3} G={2,3} B={3,3} #{4:X2}{5:X2}{6:X2}" -f $i, $r, $g, $b, $r, $g, $b)
}
if ($clrCount -gt 16) { Write-Host " ... (以下省略)" }
}
# BITMAPV5HEADER 追加フィールド
if ($biSize -ge 108 -and $bytes.Length -ge 108) {
Write-Host "`n--- BITMAPV4/V5 追加フィールド ---" -ForegroundColor Yellow
$bV4RedMask = BitConverter::ToUInt32($bytes, 40)
$bV4GreenMask = BitConverter::ToUInt32($bytes, 44)
$bV4BlueMask = BitConverter::ToUInt32($bytes, 48)
$bV4AlphaMask = BitConverter::ToUInt32($bytes, 52)
Write-Host (" RedMask : 0x{0:X8}" -f $bV4RedMask)
Write-Host (" GreenMask: 0x{0:X8}" -f $bV4GreenMask)
Write-Host (" BlueMask : 0x{0:X8}" -f $bV4BlueMask)
Write-Host (" AlphaMask: 0x{0:X8}" -f $bV4AlphaMask)
}
Write-Host "`n完了。" -ForegroundColor Green
}
# 実行
Get-DIBFromClipboard
参考
https://learn.microsoft.com/ja-jp/windows/win32/gdi/device-independent-bitmaps
https://learn.microsoft.com/ja-jp/windows/win32/wmdm/-bitmapinfoheader
https://learn.microsoft.com/ja-jp/windows/win32/api/wingdi/ns-wingdi-rgbquad
https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats
https://learn.microsoft.com/ja-jp/windows/win32/api/wingdi/ns-wingdi-bitmapv5header
https://qiita.com/ImagingSolAkira/items/30fd3727afa3076b8050
https://www5d.biglobe.ne.jp/~noocyte/Programming/Windows/BmpFileFormat.html
https://qiita.com/hon_no_mushi/items/9b9144fb9156fe618100
#tips
#メモ