[英]Transparent images with C# WinForms
I am working on a Windows Forms application in VS 2008, and I want to display one image over the top of another, with the top image being a gif or something with transparent parts.我正在 VS 2008 中处理 Windows 窗体应用程序,我想在另一个图像的顶部显示一个图像,顶部图像是 gif 或带有透明部分的东西。
Basically I have a big image and I want to put a little image on top if it, so that they kinda appear as one image to the user.基本上我有一个大图像,我想在它上面放一个小图像,这样它们就可以作为一个图像呈现给用户。
I've been trying to use a picturebox, but this doesn't seem to have worked, any suggestions?我一直在尝试使用图片框,但这似乎不起作用,有什么建议吗?
I was in a similar situation a couple of days ago.几天前我也处于类似的情况。 You can create a transparent control to host your image.
您可以创建一个透明控件来托管您的图像。
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();
}
}
}
PictureBox 有 2 层图像:BackgroundImage 和 Image,您可以独立使用它们,包括绘制和清除。
Put the big/bottom image on a PictureBox
, then add a handler to the OnPaint
event and use one of the e.Graphics.DrawImage()
overloads.将大/底部图像放在
PictureBox
,然后将处理程序添加到OnPaint
事件并使用e.Graphics.DrawImage()
重载之一。 You can load the image using Image.FromFile()
.您可以使用
Image.FromFile()
加载图像。
The small/top image will have to have an alpha channel and be transparent in the background for the overlay to work.小/顶部图像必须有一个 alpha 通道并且在背景中是透明的,这样叠加层才能工作。 You should be able to ensure this pretty easily in Photoshop or something similar.
你应该能够在 Photoshop 或类似的东西中很容易地确保这一点。 Make sure you save in a format that supports the alpha channel, such as PNG.
确保以支持 Alpha 通道的格式保存,例如 PNG。
The vb.net code (All credits to Leon Tayson): 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
A list of similar posts is referenced at the bottom of this reply.此回复底部引用了类似帖子的列表。
This reply addresses pictureBoxes and Winforms (in the other posts below, several reiterate that WPF solves this well already)这个回复解决了pictureBoxes和Winforms(在下面的其他帖子中,有几个重申WPF已经很好地解决了这个问题)
= =
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 . 5 . In the 'paint' call for the 'background_pictureBox':
在“background_pictureBox”的“paint”调用中:
= =
private void background_pictureBox_Paint(object sender, PaintEventArgs e)
{
...foreground_pictureBox_Paint(sender, e);
}
6 . 6 . Within the 'foreground_pictureBox_Paint' call, add in whatever graphics calls you want to be displayed in the foreground.
在“foreground_pictureBox_Paint”调用中,添加您希望在前台显示的任何图形调用。
This topic repeats itself in several posts it seems:这个话题似乎在几篇文章中重复出现:
how-to-make-picturebox-transparent 如何制作图片框透明
c-sharp-picturebox-transparent-background-doesnt-seem-to-work c-sharp-picturebox-transparent-background-doesnt-seek-to-work
make-overlapping-picturebox-transparent-in-c-net make-overlapping-picturebox-transparent-in-c-net
I've always found that I've had to composite the images myself, using a single picturebox or control.我总是发现我必须自己合成图像,使用单个图片框或控件。 Having two pictureboxes with transparent parts has never worked for me.
有两个带有透明部分的图片框对我来说从来没有用过。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.