31

GDI+ を使用してさまざまな色を描画します。

brush = new SolidBrush(color);
graphics.FillRectangle(brush, x, y, width, height);

ガラス上では不透明な色が適切に表示されないことがわかります。 代替テキスト

ガラスに単色を描くにはどうすればよいですか?


また、完全に不透明な色は、その色に応じて異なる方法で処理されることにも気付くでしょう。

  • 不透明な黒: 完全に透明
  • opaque color: 部分的に透明
  • 不透明な白: 完全に不透明

代替テキスト

さまざまな色がどのように処理されるかを説明しているデスクトップ コンポジターのドキュメントを誰か教えてもらえますか?


アップデート 3

FillRectangleの動作が とは異なることにも気付くでしょうFillEllipse:

  • FillEllipse不透明な色で不透明な色を描く
  • FillRectangle不透明な色で描画すると、部分的に (または完全に) 透明になります

代替テキスト

無意味な行動の説明をお願いします。

更新 4

Alwayslearningは、合成モードを変更することを提案しました。MSDNから:

CompositingMode 列挙体

CompositingMode列挙体は、レンダリングされた色を背景色と組み合わせる方法を指定します。この列挙は、 Graphicsクラスの 'Graphics::SetCompositingMode'メソッドによって使用さGraphics::GetCompositingModeれます。

CompositingModeSourceOver

色をレンダリングするときに背景色とブレンドすることを指定します。ブレンドは、レンダリングされる色のアルファ コンポーネントによって決定されます。

CompositingModeSourceCopy

色がレンダリングされるときに背景色を上書きすることを指定します。このモードは、TextRenderingHintClearTypeGridFit と一緒に使用することはできません。

の説明からCompositingModeSourceCopy、それは私が望むオプションではないように思えます。それが課す制限から、それは私が望むオプションのように思えます. そして、構成、または透明度が無効になっている場合、 SourceBlendではなくSourceCopyを実行するため、必要なオプションではありません

代替テキスト

幸いなことに、それは私の実際の問題を解決しないので、私が考えなければならない悪ではありません. オブジェクトを作成した後graphics、合成モードを変更してみました:

graphics = new Graphics(hDC);
graphics.SetCompositingMode(CompositingModeSourceCopy); //CompositingModeSourceCopy = 1

結果は出力に影響しません。

代替テキスト

ノート

  • Win32 ネイティブ
  • .NET ではない (ネイティブ)
  • Winforms ではない (すなわちネイティブ)
  • GDI+ (ネイティブ)

こちらもご覧ください

4

6 に答える 6

1

私にとってはうまくいくようです。完全なコード例がないので、合成モードが間違っていると思います。

public void RenderGdiPlus()
{
    List<string> colors = new List<string>(new string[] { "000000", "ff0000", "00ff00", "0000ff", "ffffff" });
    List<string> alphas = new List<string>(new string[] { "00", "01", "40", "80", "c0", "fe", "ff" });
    Bitmap bmp = new Bitmap(200, 300, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

    Graphics graphics = Graphics.FromImage(bmp);
    graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
    graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None;
    graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;

    graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
    graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
    SolidBrush backBrush = new SolidBrush(Color.FromArgb(254, 131, 208, 129));
    graphics.FillRectangle(backBrush, 0, 0, 300, 300);

    graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
    Pen pen = new Pen(Color.Gray);
    for (int row = 0; row < alphas.Count; row++)
    {
        string alpha = alphas[row];
        for (int column=0; column<colors.Count; column++)
        {
            string color = "#" + alpha + colors[column];
            SolidBrush brush = new SolidBrush(ColorTranslator.FromHtml(color));
            graphics.DrawRectangle(pen, 40*column, 40*row, 32, 32);
            graphics.FillRectangle(brush, 1+40*column, 1+40*row, 31, 31);
        }
    }

    Graphics gr2 = Graphics.FromHwnd(this.Handle);
    gr2.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
    gr2.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
    gr2.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None;
    gr2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
    gr2.DrawImage(bmp, 0, 0);
}
于 2010-11-26T02:37:33.970 に答える
1

別の日、私による別の解決策。

  • ガラスに表示するすべてのものをビットマップに描画します。
  • 次に、フォームの背景を黒色でクリアします。
  • この直後に、フォームにビットマップを描画します。

ただし (DrawThemeTextEx を使用しない他のソリューションと同様): テキスト レンダリングは正しく機能しません。これは、常にフォームの背景色をアンチエイリアス/cleartype ヒントとして使用するためです。代わりに、グロー効果のあるテキストもサポートする DrawThemeTextEx を使用してください。

于 2015-01-28T13:54:48.603 に答える
0

GDIで同じ問題に遭遇しました。
GDI はゼロのアルファ チャネル値を使用するため、最も簡単な解決策は、次のコードのようにアルファ チャネルを修正することです。

void fix_alpha_channel()
{
    std::vector<COLORREF> pixels(cx * cy);

    BITMAPINFOHEADER bmpInfo = {0};
    bmpInfo.biSize = sizeof(bmpInfo);
    bmpInfo.biWidth = cx;
    bmpInfo.biHeight = -int(cy);
    bmpInfo.biPlanes = 1;
    bmpInfo.biBitCount = 32;
    bmpInfo.biCompression = BI_RGB;

    GetDIBits(memDc, hBmp, 0, cy, &pixels[0], (LPBITMAPINFO)&bmpInfo, DIB_RGB_COLORS);

    std::for_each(pixels.begin(), pixels.end(), [](COLORREF& pixel){
        if(pixel != 0) // black pixels stay transparent
            pixel |= 0xFF000000; // set alpha channel to 100%
    });

    SetDIBits(memDc, hBmp, 0, cy, &pixels[0], (LPBITMAPINFO)&bmpInfo, DIB_RGB_COLORS);
}
于 2011-05-17T10:42:56.110 に答える