none
TransparentBltでの透過処理で特定のPCで黒(0,0,0)が透過しない RRS feed

  • 質問

  • Visual Studio2017でMFCでのGUIアプリケーションを作成しております。

    背景画像をGUI上に表示させてその上にレイヤー画像を表示します。
    そのレイヤー画像の黒(0,0,0)部分を透過させて表示しようとしています。

    TransparentBltでRGB(0, 0, 0)と指定して透過させています。

    ところが、別のPCで動作させると黒の部分がまったく透過せずに表示されてしまいました。

    三台のPCで見てみましたが、
    ・Windows 7  64bit デスクトップ(メインPC)    透過OK
    ・Windows 10 64bit デスクトップ(デバッグPC)    透過OK
    ・Windows 10 64bit ノート(デバッグPC)        透過NG

    ノートPCで動作させた時だけ透過しませんでした。

    画像の黒を(1,1,1)にしてTransparentBltでRGB(1, 1, 1)とすればノートPCでも透過しました。

    黒(0,0,0)にすると透過しなくなります。

    いずれも同じGUIアプリを動作させています。
    処理の問題なのかWindows上の問題なのか正直お手上げ状態です。

    AlphaBlendも設定してみたりしましたが変わりませんでした。

    BLENDFUNCTION bf;
    bf.BlendOp = AC_SRC_OVER;
    bf.BlendFlags = 0;
    bf.AlphaFormat = 0;
    bf.SourceConstantAlpha = 0;

    何か情報をお持ちの方がいらっしゃいましたら
    ご教授頂けませんでしょうか。

    よろしくお願い致します。

    2019年8月1日 7:03

回答

  • 亀レスですが、
    動作不良のPCでは、TransparentBlt()の戻り値はTRUE/FALSEのどちらが戻っているか確かめるべきかもしれません。
    FALSEが戻っている場合、関数は「失敗」しているので、透過色としてRGB(0,0,0)は使えないことが明らかになります。
    TRUEが戻っている場合は、OSの動作不良となります。

    最終的には透過色を変更しなければならないかもしれません。

    以下は蛇足です。

    現在のAPIでは全てのフォーマットに対応していると明記されていますが、TransparentBlt()はかつては4、8bitのビットマップだけを対象にしていました。
    それで、使える色数が少ないため、透過色に使用頻度の少ないマゼンタ=RGB(255,0,255)等を使用していました。
    VSがかつて提供していたツールバー用のビットマップも透過色にこの色を使用しています。
    似たような判断をしたのかもしれません。

    2019年8月7日 2:51

すべての返信

  • Hiroshi626さん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    画像に関する詳細情報をご提供いただけますでしょうか。これは32 bppビットマップですか。
    TransparentBlt関数は、ソースビットマップのすべての形式をサポートしています。 
    ただし、32 bppビットマップの場合、アルファ値がコピーされるだけです。 
    AlphaBlendを使用して、32ビット/ピクセルのビットマップと透明度を指定します。

    コピー元とコピー先の四角形が同じサイズでない場合、コピー元のビットマップはコピー先の四角形に合わせて拡大されます。 
    SetStretchBltMode関数を使用すると、BLACKONWHITEおよびWHITEONBLACKのiStretchModeモードがTransparentBlt関数のCOLORONCOLORに変換されます。 

    PCのディスプレイ設定が一貫しているかどうかを確認することをお勧めします。

    どうぞよろしくお願いします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2019年8月6日 8:28
    モデレータ
  • Haruka様

    返信ありがとうございます。

    32bppビットマップです。

    読み込むBMPファイル自体は8bit(256色)のファイルですが、
    表示する時に32bitに変換しています。

        CBitmap  bmp;
        bmp.CreateBitmap(Width, Height, 1, 32, RGBData);

    読み込んだファイルのRGBデータをRGBDataに格納してあります。
    32bitにするので4BYTE単位で格納しており、
    4BYTE目には0x00を入れてあります。


    > PCのディスプレイ設定が一貫しているかどうかを確認することをお勧めします。
    ディスプレイ設定を確認しましたが同じでした、
    [スタート]-[設定]-[システム](Windows10)

    具体的にどの辺りを確認するべきかとかありますでしょうか。

    すみませんが
    よろしくお願い致します。


    2019年8月7日 2:08
  • 亀レスですが、
    動作不良のPCでは、TransparentBlt()の戻り値はTRUE/FALSEのどちらが戻っているか確かめるべきかもしれません。
    FALSEが戻っている場合、関数は「失敗」しているので、透過色としてRGB(0,0,0)は使えないことが明らかになります。
    TRUEが戻っている場合は、OSの動作不良となります。

    最終的には透過色を変更しなければならないかもしれません。

    以下は蛇足です。

    現在のAPIでは全てのフォーマットに対応していると明記されていますが、TransparentBlt()はかつては4、8bitのビットマップだけを対象にしていました。
    それで、使える色数が少ないため、透過色に使用頻度の少ないマゼンタ=RGB(255,0,255)等を使用していました。
    VSがかつて提供していたツールバー用のビットマップも透過色にこの色を使用しています。
    似たような判断をしたのかもしれません。

    2019年8月7日 2:51
  • 仲澤@失業者 様

    返信ありがとうございます。

    TransparentBlt()の戻り値を確認してみましたところ、
    TRUEで返ってきていました。

    OSの動作不良ということになるんでしょうか…。

    透過色の変更は一応考えていました。
    処理も作ってあり今はコメントアウトしています。

    ただ、BMP読込時にRGB(0,0,0)の部分を全てRGB(1,1,1)に変換して
    透過色をRGB(1,1,1)にするだけなんですが。
    これであれば透過することは確認できました。

    読込時に余計な処理を入れずに
    読み込んだままの状態で透過できればよかったのですが。

    透過色の変更処理を有効にして、
    RGB(1,1,1)での透過を行うようにします。


    情報感謝致します。
    2019年8月7日 5:35