0

オブジェクトをコンテナ内にスタックできるようにするGUIを作成するように依頼されました。ユーザーは、ボックスを上から下の視点から表示します。彼らはまた、中に何が積み重ねられているかを見たいと思っています。これを解決するために最初に考えたのは透明性でした。透明度に関する投稿をいくつか読んだことがありますが、両方の画像が透明であるという問題を解決するものは見つからなかったため、積み重ねても両方を見ることができました。

コントロールを他のコントロールと一緒に透明にするにはどうすればよいですか。これが実際には不可能な場合。この問題へのより良いアプローチは何ですか?

この問題を解決するために、カスタムコントロール(パブリック部分クラスMyControl:Control)を使用しています。ついにコントロールの画像が透明になりました。親フォームに描画されたものはすべて画像を通して表示されます(親が楕円と正方形をペイントするためにonPaintを使用しています)が、その上に配置された他のコントロールは透明ではなくなりました。

これを実現するために使用しているコードは次のとおりです。

public Image Image 
  {
     get { return m_Image; }
     set { m_Image = value; }
  }
private void GridControl_Paint(object sender, PaintEventArgs e)
  {
     if (Image != null)
     {

        Graphics g = e.Graphics;
        Bitmap bitMap = new Bitmap(Image);

        //This is not working... the color array always comes back empty
        //This is how I would rather making things transparent...
        Color[] colorArray = bitMap.Palette.Entries;

        if (colorArray.Length > 0)
        {

           ColorMap[] colorMap = new ColorMap[colorArray.Length];

           for (int index = 0; index < colorArray.Length; index++)
           {
              colorMap[index] = new ColorMap();
              colorMap[index].OldColor = colorArray[index];
              colorMap[index].NewColor = Color.Transparent;
           }

        }

        //Ok fine so the above is not working... let me force it.
        //Get each pixel in the image and change the color.
        else
        {
           for (int x = 0; x < bitMap.Width; x++)
           {
              for (int y = 0; y < bitMap.Height; y++)
              {
                 Color pixelColor = bitMap.GetPixel(x, y);
                 Color newColor = Color.FromArgb(100, pixelColor);

                 bitMap.SetPixel(x, y, newColor);
              }
           }
        }

        bitMap.MakeTransparent();

        g.DrawImage(bitMap, this.ClientRectangle);
     }

  } 
4

2 に答える 2

1

WinForms の使用に縛られていませんか? 適度にトリッキーなグラフィック処理 (説明など) を行う必要があり、それを回避するためにアプリを再設計できない場合は、WPF に飛び込むことができます。

GDI+ グラフィックスでプレイしてからしばらく経ちましたので、ここにアイデアを示します (ただし、コードはありません ;) ):

積み重ねられたコントロールは実際に機能する必要がありますか? そうでない場合は、外観をビットマップにコピーして非表示にし、そのビットマップを独自のペイント ルーチンで使用できます。コントロールを機能させる必要がある場合は、それを再表示できます。

ところで、bitmap.GetPixel または SetPixel を使用すると非常に遅くなります。これは、32ビットのビットマップを操作した古いコードです(青、緑、赤、アルファはバイトです):

BitmapData bmpData = bitmap.LockBits(pixelRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

unsafe
{
    byte* bytes = (byte*)bmpData.Scan0;
    for (int row = 0; row < pixelRect.Height; row++)
    {
        for (int col = 0; col < pixelRect.Width * 4; ) // * 4: 4 bytes per pixel 
        {
            bytes[row * bmpData.Stride + col++] = blue;
            bytes[row * bmpData.Stride + col++] = green;
            bytes[row * bmpData.Stride + col++] = red;
            bytes[row * bmpData.Stride + col++] = alpha;
        }
    }
}

// Unlock the bits.
bitmap.UnlockBits(bmpData);
于 2009-05-08T14:21:58.413 に答える
0

私はこの問題の良い解決策を見つけることができませんでした。これを行うために私が見つけた唯一の方法は、カスタムコントロールを作成し、多くのカスタムコードを使用することです(まだ完全には機能していません)。答えは次のとおりです。このスレッドを閉じます。

このフォーラムで答えるのは複雑すぎます。

于 2009-09-23T15:25:47.143 に答える