(XP・VC2005・MFC)
以下のソースで処理を行ったところ、結果のResult.bmpは、全部RGB(4,4,4)になってしまいました。
透明度をいじっても同じ結果になりました(ただ、255のときだけRGB(0,0,0)になりました)。
黒地に、黒色の半透明を重ねても、結果は黒になると思っていたのですが、これは何故なのでしょうか?
#include "atlimage.h"
void CimagetestDlg::OnBnClickedButton1()
{
// GryaScaleパレット
RGBQUAD rgb[256];
for( int i = 0 ; i < 256 ; i ++ ){
rgb[i].rgbBlue = i;
rgb[i].rgbGreen = i;
rgb[i].rgbRed = i;
rgb[i].rgbReserved= 0;
}
CImage Img1,Img2;
Img1.Create( 1024,100,8); Img1.SetColorTable(0,256,rgb);
Img2.Create( 1024,100,8); Img2.SetColorTable(0,256,rgb);
CRect rec; rec.SetRect(0,0,1024,100);
HDC hdc1 = Img1.GetDC();
HDC hdc2 = Img2.GetDC();
FillRect( hdc1 ,&rec , (HBRUSH)GetStockObject(BLACK_BRUSH));
FillRect( hdc2 ,&rec , (HBRUSH)GetStockObject(BLACK_BRUSH));
Img2.ReleaseDC(); // Img2のDC開放
Img2.AlphaBlend( hdc1 , 0 , 0 , 128 , AC_SRC_OVER );
Img1.ReleaseDC();
Img1.Save("c:\\Result.bmp");
Img1.Destroy();
Img2.Destroy();
}
> 結果は黒になると思っていたのですが、これは何故なのでしょうか?
CImage::AlphaBlend()の内部で使用しているであろう(2005のソースが無いので予想だが)
AlphaBlend()API関数の仕様のような気がする。
AlphaBlend()API関数は、色深度が256以下のケースでは思い切った減色処理をしてからBlendをしている模様。
RGB の要素値が、0-7 は [4]、8-15 は [12]、...という感じに。
数式で示すと、
color.red = (color.red & 0xf8) + 4;
color.green = (color.green & 0xf8) + 4;
color.blue = (color.blue & 0xf8) + 4;
という感じかな。
で、今回の「RGB(0, 0, 0)」の場合だと
1、paletteから RGB(0, 0, 0) の近似色取得 = 「rgb[0](提示ソースから)」 = RGB(0, 0, 0)
2、RGB(0, 0, 0)を上記減色処理で「RGB(4, 4, 4)」に置換。
3、RGB(4, 4, 4) と RGB(4, 4, 4) をblend = 同値のblendなのでalpha値に関わらずRGB(4, 4, 4)
4、palatte内から RGB(4, 4, 4) の近似色を取得 = rgb[4]の色
5、結果Result.bmpは、全部「RGB(4, 4, 4) == rgb[4]」
となる。
まぁ、palette使うような状況でAlphablendなんて無茶言われても…、って事かな。
> ただ、255のときだけRGB(0,0,0)になりました
255の時だけは処理方法が異なるためと思われる。
http://msdn2.microsoft.com/en-us/library/ms532306.aspx
ちなみに上記記述内容は公式資料から得たものでは無いので注意。
+調査環境は「OS:WinXP, VC++6.0sp6, PFSDK:Feb/2003」で、環境に依っては結果が異なる可能性有。
返答ありがとうございます
>まぁ、palette使うような状況でAlphablendなんて無茶言われても…、って事かな。
無茶に近いことなんですね
8ビットのままで透過色指定と全体の透明度の変更の両方を使いたくて迷っていたのですが
踏ん切りつけて、32ビット+createAlphaChannelの組み合わせを利用する方法を選択することにしました。
ツイート | ![]() |