【问题标题】:Transparent images with C# WinForms使用 C# WinForms 的透明图像
【发布时间】:2010-09-28 13:23:33
【问题描述】:

我正在开发一个 VS 2008 中的 Windows 窗体应用程序,我想在另一个图像的顶部显示一个图像,顶部图像是 gif 或带有透明部分的东西。

基本上我有一张大图,如果有的话,我想在上面放一张小图,这样它们对用户来说就好像一张图片。

我一直在尝试使用图片框,但这似乎不起作用,有什么建议吗?

【问题讨论】:

标签: c# .net image transparency picturebox


【解决方案1】:

几天前我也遇到了类似的情况。您可以创建一个透明控件来托管您的图像。

using System;
using System.Windows.Forms;
using System.Drawing;

public class TransparentControl : Control
{
    private readonly Timer refresher;
    private Image _image;

    public TransparentControl()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        BackColor = Color.Transparent;
        refresher = new Timer();
        refresher.Tick += TimerOnTick;
        refresher.Interval = 50;
        refresher.Enabled = true;
        refresher.Start();
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20;
            return cp;
        }
    }

    protected override void OnMove(EventArgs e)
    {
        RecreateHandle();
    }


    protected override void OnPaint(PaintEventArgs e)
    {
        if (_image != null)
        {
            e.Graphics.DrawImage(_image, (Width / 2) - (_image.Width / 2), (Height / 2) - (_image.Height / 2));
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
       //Do not paint background
    }

    //Hack
    public void Redraw()
    {
        RecreateHandle();
    }

    private void TimerOnTick(object source, EventArgs e)
    {
        RecreateHandle();
        refresher.Stop();
    }

    public Image Image
    {
        get
        {
            return _image;
        }
        set
        {
            _image = value;
            RecreateHandle();
        }
    }
}

【讨论】:

  • Whats the Hack 因为我没有看到内部调用了 Redraw。什么时候需要调用?
  • 如您所见,它是公开的。 IIRC,我在调整锚定透明控件的形式时遇到了一个错误。我认为它从表单中消失了,所以我把那个 Redraw 方法从表单的 resize 中调用。
  • 效果很好。我面临的唯一问题是,与 PictureBox 不同,我无法将其设置为自动调整大小或拉伸。除此之外,它就像一个魅力。谢谢莱昂!
  • 定时器/刷新有什么用?
  • 设置ControlFlags.ResizeRedraw.
【解决方案2】:

PictureBox 有 2 层图像:BackgroundImage 和 Image,可以相互独立使用,包括绘图和清除。

【讨论】:

    【解决方案3】:

    将大/底部图像放在PictureBox 上,然后将处理程序添加到OnPaint 事件并使用e.Graphics.DrawImage() 重载之一。您可以使用Image.FromFile() 加载图像。

    小/顶部图像必须有一个 Alpha 通道并且在背景中是透明的,这样叠加才能起作用。您应该能够在 Photoshop 或类似软件中轻松确保这一点。确保以支持 Alpha 通道的格式保存,例如 PNG。

    【讨论】:

      【解决方案4】:

      vb.net 代码(全部归功于 Leon Tayson):

      Imports System
      Imports System.Windows.Forms
      Imports System.Drawing
      
      Public Class TransparentControl
          Inherits Control
      
          Private ReadOnly Local_Timer As Timer
          Private Local_Image As Image
      
          Public Sub New()
              SetStyle(ControlStyles.SupportsTransparentBackColor, True)
              BackColor = Color.Transparent
              Local_Timer = New Timer
              With Local_Timer
                  .Interval = 50
                  .Enabled = True
                  .Start()
              End With
      
              AddHandler Local_Timer.Tick, AddressOf TimerOnClick
      
          End Sub
      
          Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
              Get
                  Dim cp As CreateParams
                  cp = MyBase.CreateParams
                  cp.ExStyle = &H20
                  Return cp
              End Get
          End Property
      
          Protected Overrides Sub OnMove(ByVal e As System.EventArgs)
              MyBase.OnMove(e)
              RecreateHandle()
          End Sub
      
          Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
              MyBase.OnPaint(e)
      
              If Local_Image IsNot Nothing Then _
                  e.Graphics.DrawImage(Local_Image, New Rectangle(0, 0, (Width / 2) - (Local_Image.Width / 2), (Height / 2) - (Local_Image.Height / 2)))
      
          End Sub
      
          Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
              ' DO NOT PAINT BACKGROUND
          End Sub
      
          ''' <summary>
          ''' Hack
          ''' </summary>
          ''' <remarks></remarks>
          Public Sub ReDraw()
              RecreateHandle()
          End Sub
      
          Private Sub TimerOnClick(ByVal sender As Object, ByVal e As System.EventArgs)
              RecreateHandle()
              Local_Timer.Stop()
      
          End Sub
      
          Public Property Image As Image
              Get
                  Return Local_Image
              End Get
              Set(ByVal value As Image)
                  Local_Image = value
                  RecreateHandle()
              End Set
          End Property
      End Class
      

      【讨论】:

      • 这个怎么用?
      【解决方案5】:

      此回复底部引用了类似帖子的列表。

      此回复涉及图片框和 Winforms(在下面的其他帖子中,有几个重申 WPF 已经很好地解决了这个问题)

      1. 创建 Winform
      2. 创建 x2 个图片框
        • foreground_pictureBox // 图片框在“背景”的“前面”
        • background_pictureBox //“前景”“后面”的图片框
      3. 为每个图片框添加“绘制”事件
        • 在“设计器”中选择对象
        • 选择“属性”选项卡(或右键单击并从弹出菜单中选择)
        • 选择事件按钮(小闪电)
        • 双击“paint”事件右侧的空白字段
      4. 将以下代码添加到主窗体的“加载”函数中(如果尚未添加,请使用步骤 3 中的方法并选择“加载时”而不是“绘制”)

      =

      private void cFeedback_Form_Load(object sender, EventArgs e)
      {
          ...
          // Ensure that it is setup with transparent background
          foreground_pictureBox.BackColor = Color.Transparent;
      
          // Assign it's 'background'
          foreground_pictureBox.Parent = background_pictureBox;
          ...
      }
      

      5 .在 'background_pictureBox' 的 'paint' 调用中:

      =

      private void background_pictureBox_Paint(object sender, PaintEventArgs e)
      {
          ...foreground_pictureBox_Paint(sender, e);
      }
      

      6 .在“foreground_pictureBox_Paint”调用中,添加您希望在前景中显示的任何图形调用。

      这个话题似乎在几篇文章中重复出现:

      how-to-make-picturebox-transparent

      c-sharp-picturebox-transparent-background-doesnt-seem-to-work

      make-overlapping-picturebox-transparent-in-c-net

      a-picturebox-problem

      【讨论】:

        【解决方案6】:

        我一直发现我必须自己合成图像,使用单个图片框或控件。拥有两个带有透明部分的图片框对我来说从来没有用过。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-04-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-04
          • 2014-09-17
          相关资源
          最近更新 更多