私の目標は、動的にHICONイメージにいくつかの任意のテキストを置くことです、私は次のコードを使用しています(実行時に。):GDIを使用して透明度を持つテキストを描画する方法は?
//Error checks are omitted for brevity
//First create font
LOGFONT lf = {0};
lf.lfHeight = -58;
lf.lfWeight = FW_NORMAL;
lf.lfOutPrecision = OUT_TT_PRECIS; //Use TrueType fonts for anti-alliasing
lf.lfQuality = CLEARTYPE_QUALITY;
lstrcpy(lf.lfFaceName, L"Segoe UI");
HFONT hFont = ::CreateFontIndirect(&lf);
//HICON hIcon = original icon to use as a source
//I'm using a large 256x256 pixel icon
hIcon = (HICON)::LoadImage(theApp.m_hInstance, MAKEINTRESOURCE(IDI_ICON_GREEN_DIAMOND), IMAGE_ICON, 256, 256, LR_DEFAULTCOLOR);
ICONINFO ii = {0};
::GetIconInfo(hIcon, &ii);
BITMAP bm = {0};
::GetObject(ii.hbmColor, sizeof(bm), &bm);
SIZE szBmp = {bm.bmWidth, bm.bmHeight};
HDC hDc = ::GetDC(hWnd);
HDC hMemDC = ::CreateCompatibleDC(hDc);
HGDIOBJ hOldBmp = ::SelectObject(hMemDC, ii.hbmColor);
HGDIOBJ hOldFont = ::SelectObject(hMemDC, hFont);
::SetBkMode(hMemDC, TRANSPARENT);
::SetTextColor(hMemDC, RGB(255, 0, 0)); //Red text
//Draw text
//NOTE that DrawText API behaves in a similar way
::TextOut(hMemDC, 0, 0, L"Hello", 5);
::SelectObject(hMemDC, hOldFont);
::SelectObject(hMemDC, hOldBmp);
//We need a simple mask bitmap for the icon
HBITMAP hBmpMsk = ::CreateBitmap(szBmp.cx, szBmp.cy, 1, 1, NULL);
ICONINFO ii2 = {0};
ii2.fIcon = TRUE;
ii2.hbmColor = ii.hbmColor;
ii2.hbmMask = hBmpMsk;
//Create updated icon
HICON hIcon2 = ::CreateIconIndirect(&ii2);
//Cleanup
::DeleteObject(hBmpMsk);
::DeleteDC(hMemDC);
::ReleaseDC(hWnd, hDc);
::DeleteObject(ii.hbmColor);
::DeleteObject(ii.hbmMask);
::DeleteObject(hFont);
をして、私は(OnPaint()
ハンドラからの私のウィンドウにアイコンを表示することができます私のような)ことが判明どのように見ることができる。
::DrawIconEx(dc.GetSafeHdc(), 0, 0,
hIcon2,
256, 256, NULL,
::GetSysColorBrush(COLOR_BTNFACE),
DI_NORMAL);
は、だからここに私が得るものです:
hIcon2
でピクセル単位で起こっていることを見るには、上記のコードのをii.hbmColor
と呼びました。ピクセルがそのメモリダンプにBGRA
としてエンコードされ、その各DWORDにおける第4バイトは、透明性を意味している
:私の言葉「こんにちは」がこのように見え示されることになった。得られた画素アレイ0 =透明、FF =不透明。しかし、この場合、TextOut
は透明度を記入しないか、0として残します。これは「完全透過」と解釈されます。代わりに、それをあらかじめ色に掛けているようです。私は緑のダイヤモンドが始まる同じビットマップ、さらに下探し続ける場合は、画像のピクセルは透明性を持っているように見えること
注意が正しく設定バイト:
任意のアイデアはどのようにテキストを描画しますAPIはそれらの透過バイトを設定できますか?
編集:私は、次のGDI +の方法を試みたの下ようが示唆された。
HGDIOBJ hOldBmp = ::SelectObject(hMemDC, ii.hbmColor);
Graphics grpx(hMemDC);
RectF rcfTxt(0.0f, 0.0f, (REAL)szBmp.cx, (REAL)szBmp.cy);
Font gdiFont(L"Segoe UI", 58.0f, FontStyleRegular, UnitPixel);
SolidBrush gdiBrush(Color(255, 0, 0));
StringFormat gdiSF;
gdiSF.SetAlignment(StringAlignmentNear);
gdiSF.SetFormatFlags(StringFormatFlagsNoWrap);
gdiSF.SetHotkeyPrefix(HotkeyPrefixNone);
//The reason I was using GDI was because I was setting
//spacing between letters using SetTextCharacterExtra()
//Unfortunately with GDI+ this does not work!
HDC hTmpDC = grpx.GetHDC();
::SetTextCharacterExtra(hTmpDC, -4); //This doesn't do anything!
grpx.ReleaseHDC(hTmpDC);
grpx.DrawString(L"Hello", 5, &gdiFont, rcfTxt, &gdiSF, &gdiBrush);
::SelectObject(hMemDC, hOldBmp);
と(私はGDIとSetTextCharacterExtra
を使用できます)文字間隔を設定することができない以外は、ここで私は(少し得たものです)視認性の拡大:透明性
だから、明らかにまだ問題。
GDIはアルファを理解しません。代わりにgdiplusを考慮する。 –
@ JonathanPotter:ありがとう。 GDI +はアルファチャンネルをサポートする唯一の方法だと思われます。私が単純なGDIを使った理由は、['SetTextCharacterExtra'](https://msdn.microsoft.com/en-us/library/windows/desktop/dd145092(v = vs.85).aspx)を提供したためです。文字間隔を変更する機能。私はまだGDI +でそれを使用できるかどうか知っていますか? – c00000fd