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 位位图(其中蓝色、绿色、红色和 alpha 是字节)周围的一些旧代码:

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 回答