3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

え?嘘、私のBMP、非準拠すぎ? OpenCV 4.13でAlphaも正しく保存できるってよ!

3
Last updated at Posted at 2025-12-04

■ TL;DR あなたのBMP、実は"非準拠"かも?

  • 現象:α付き画像をBMP保存 → ビューアで透過情報が消えちゃう!やだー!
  • 原因:OpenCVが BGRX(Extra) 形式でファイル保存!Xに透過度情報を入れていたので、アプリによって扱いマチマチ
  • 解決OpenCV 4.13 から BGRA(本物のα) として保存できるように!

■ はじめに

OpenCVで何もコーデック有効にしなくても使える実は便利なBMP Encoder/Decoder。ところが、OpenCV 4.12.0以前だとちょーっと困った振る舞いしてました。

□ Microsoft曰く

BITMAPINFOHEADERには詳細が書いてないので、仕方が無いのでBITMAPV5HEADERで。

ビットマップの色は最大 2^32 です。 BITMAPV5HEADERの bV5Compression メンバーがBI_RGB場合、BITMAPINFO の bmiColors メンバーは NULL になります。 ビットマップ配列の各 DWORD は、ピクセルの青、緑、赤の相対的な強度を表します。 blue の値は、最下位の 8 ビットで、その後に緑と赤のそれぞれ 8 ビットが続きます。 各 DWORD の上位バイトは使用されません

お分かりいただけるだろうか・・・ 32bitで保存する場合、B,G,R,A(Alpha)ではなく、BGRX(extra)で保存されるのである…。というか、X部分は使われないと断言されている。アルファじゃない!!

つまり、OpenCVで、CV_8UC4の画像を作ってBMPファイルに保存しても、IMREAD_UNCHANGEDフラグ付きで読み込むとCV_8UC3の画像で戻ってくるのは、マイクロソフトさんの仕様準拠なら当たり前!ということですね…… 😢

ただし実はこれ、OpenCV側でEncoderとDecoderで仕様が食い違ってるバグがあったりしたわけなのです。

RI_RGB

Encoder Decoder
(IMREAD_UNCHANGED)
CV_8UC3 3ch :sunny: 3ch :sunny:
CV_8UC4 4ch :umbrella: 非準拠 3ch :snowman2: (読み込めず)

□ OpenCV v4.13.0からは

OpenCV v4.13.0からは、4ch(32bpp)の画像データを保存するときに(デフォルトで)RI_BITFIELDSを使ってαチャネルも保存できるようになりましたー!!つまり、cv::IMREAD_UNCHANGEDを指定すると、4チャンネルがかえってくるよー!

「いやいや、うちの連携アプリはRI_BMPしか使えんのよ。そう簡単に変えられても困る・・・」という声もあるかもしれないので、互換モードも完備でございます!

RI_BITFIELDS

Encoder Decoder
(IMREAD_UNCHANGED)
CV_8UC4 4ch :sunny: 4ch :sunny:
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <iostream>

int main()
{
  cv::Mat src(320,240, CV_8UC4, cv::Scalar(64,128,92,45));
  cv::imwrite("src.bmp", src);
  cv::Mat dst;
  dst = cv::imread("src.bmp", cv::IMREAD_UNCHANGED);
  std::cout << src.channels() << std::endl;
  std::cout << dst.channels() << std::endl;

  return 0;
}
$ ./a.out
4
4

□ で、解決だと思うじゃろ?クックックック...

さて、規格マニアな方にはもう一歩。実はこの‘BI_BITFIELDS'でAlphaチャネルって仕様準拠でじゃないともいえるのです👿

bV5RedMask
 各ピクセルの赤の成分を指定するカラー マスク。 bV5Compression が BI_BITFIELDS に設定されている場合にのみ有効です。
bV5GreenMask
 各ピクセルの緑のコンポーネントを指定するカラー マスク。 bV5Compression が BI_BITFIELDS に設定されている場合にのみ有効です。
bV5BlueMask
 各ピクセルの青色の成分を指定するカラー マスク。 bV5Compression が BI_BITFIELDS に設定されている場合にのみ有効です。
bV5AlphaMask
 各ピクセルのアルファ 成分を指定するカラー マスク。

あれ? bV5AlphaMaskが何時、有効なのか書いてない 、ということは厳密にいうと……(げほんごほん)

■ まとめ:あなたのBMP、実は"非準拠"かも?

  • 現象:α付き画像をBMP保存 → ビューアで透過情報が消えちゃう!やだー!
  • 原因:OpenCVが BGRX(Extra) 形式でファイル保存!Xに透過度情報を入れていたので、アプリによって扱いマチマチ
  • 解決OpenCV 4.13 から BGRA(本物のα) として保存できるように!

明日は 「[Universal Intrinsic] vc=va+vb; はもうダメです。突然こんな事いってごめんね。でも本当です。」 です!! 実はもうUniversal Intrinsicでこの書き方は使えません!ビルドエラーになってしまいます!!ということで、ちょーっとだけ新しいやり方を覚えていってください、簡単ですから!!というご紹介になります。お楽しみに!!

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?