【问题标题】:Transparent image over a control控件上的透明图像
【发布时间】:2018-09-19 13:49:06
【问题描述】:

我正在做一个带有闪屏的应用程序。

我有一张图片,我想将其放在进度条下方,例如:

示例

我已成功使位图透明。 但是,现在,图像在进度条的后面

现在

有没有办法让进度条前面的图像? 谢谢你。 F.

代码:

public partial class Form1 : Form
{
    Bitmap m_l;
    public Form1()
    {
        InitializeComponent();

        m_l = Properties.Resources.LU;

        m_l.MakeTransparent(Color.Transparent);
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawImage(m_l, new Rectangle(new Point(0, -40), new Size(200, 264))); progressBar1.Refresh();
    }
}

【问题讨论】:

标签: c# winforms bitmap


【解决方案1】:

(对不起,错过了答案功能,但答案是渴望评论)

@TaW 看来你不是很了解这个方法,所以我会尝试更详细地解释它

OP 询问他是否可以在另一个控件(进度条)上制作透明图像

我假设这个透明图像在 PictureBox 内,你似乎假设有其他控件

要定位控件,如果我的假设是正确的图片框,他所要做的就是右键单击并单击图片框上的“放在前面”

你在进度条前面有一个“透明”图片框 - 但正如你在回答中提到的那样,我们不能停在那里,因为“透明”不是我所期望的,但显然你知道 - 它是这种“父背景颜色”选择”WinForms 所做的那样,我们最终会在 ProgressBar 前面得到一个不完全透明的图像,而是一个带有灰色背景的图像

现在发布的网址已经到位: http://www.richardhyland.com/diary/2009/05/26/how-to-truely-make-a-picturebox-background-transparent/

这是提供的代码,并在该网址中进行了解释:

public static System.Drawing.Drawing2D.GraphicsPath Transparent(Image im)
{
    int x;
    int y;
    Bitmap bmp = new Bitmap(im);
    System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();
    Color mask = bmp.GetPixel(0, 0);

    for (x = 0; x <= bmp.Width - 1; x++)
    {
        for (y = 0; y <= bmp.Height - 1; y++)
        {
            if (!bmp.GetPixel(x, y).Equals(mask))
            {
                gp.AddRectangle(new Rectangle(x, y, 1, 1));
            }
        }
    }
    bmp.Dispose();
    return gp;
}

这样我们可以在进度条前面实现一个完全透明的图片框。

所以没有这个代码,我们有这个:

但使用该代码:

注意,这种方法有一些缺点:

  1. 效果不佳 - 您可以看到图像边缘周围的灰色像素
  2. 在大图像上表现不佳 - 因为使用GetPixel 获取每个像素是“挑战”

(请忽略图片显示“JPG”的事实,我说的是透明图片 - 这只是 Google 搜索向我展示的第一张图片,是的,该文件是透明 png)

【讨论】:

  • 答案应该包括正确归属的代码,以防链接失效。在大图像上使用 GetPixel 性能会很差。
  • @LarsTech - 更新了我的“答案”以反映您的评论
  • 请注意,要解决 GetPixel 性能问题,您可以使用 LockBits。优化区域以包含更少的一个像素矩形将是一个更大的挑战。就目前而言,它具有与不透明像素一样多的矩形。但是在这里这肯定是没有必要的..
【解决方案2】:

您可以使用PictureBoxRegion 来完成此操作。

在您的表单中添加PictureBox。这将保存图像。根据需要将其放置在与ProgressBar 重叠的位置。将 Image 属性设置为覆盖图像。

在表单构造函数中,我们将设置这个PictureBoxRegion。该区域定义了控件的形状。我们将设置Region 等于图像的不透明部分。

public partial class Form1 : Form
{
  public Form1()
  {
    InitializeComponent();
    pictureBox1.Region = CreateRegion(Properties.Resources.LU);
  }

  private static Region CreateRegion(Bitmap maskImage)
  {
    // We're using pixel 0,0 as the "transparent" color.
    Color mask = maskImage.GetPixel(0, 0);
    GraphicsPath graphicsPath = new GraphicsPath();
    for (int x = 0; x < maskImage.Width; x++)
    {
      for (int y = 0; y < maskImage.Height; y++)
      {
        if (!maskImage.GetPixel(x, y).Equals(mask))
        {
          graphicsPath.AddRectangle(new Rectangle(x, y, 1, 1));
        }
      }
    }

    return new Region(graphicsPath);
  }
}

大部分代码来自here

【讨论】:

  • 该代码看起来非常接近另一个答案,该答案来自另一篇文章。您应该正确地注明该代码的作者。
【解决方案3】:

5 6个选项:

  1. 您可以将ProgressBar's BackColor 设置为Transparent。结果:

翻译:

属性值无效。此控件不支持透明背景色。

这也适用于子类。

  1. 您可以嵌套一个透明的Panel,并将图像作为其BackgroundImage。结果:

如您所见,尽管面板和大部分图像都是透明的,但进度条仍然在它自己的BackColor 中使用一个矩形覆盖它;见上文,它不可能是透明的。

  1. 您可以用面板叠加

结果:

看起来很相似。但这一次背景色是面板在覆盖之前所在位置的原始背景。这就是 winform 伪造透明度的方式;这种伪造的透明度仅适用于嵌套控件,但不适用于所有..

  1. 您可以在进度条的Paint 事件中绘制图像。问题:它没有一个。如果您将其子类化,它将对您不起作用。

总结一下:所有这些尝试失败;结论很简单:ProgressBar 是一个动画控件,不支持任何对其进行处理。

  1. 最后一个选项:自己写。您可以将PanelLabel 子类化并编写自己的进度条。许多想要定制外观的人都这样做了,您可以找到许多现成的示例。

更新:看起来你可以有第 6 个选项,当且仅当你不需要半透明,如抗锯齿等。 .: 您可以创建一个GraphicsPath 来创建一个Region,这将掩盖图像的一些控制。因此,虽然我的示例不起作用,但 OP 的图像可能看起来还不错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2016-12-06
    • 2010-11-22
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    相关资源
    最近更新 更多