问题描述
当我尝试使用透明背景时,它不是完全透明的.我为此问题尝试了两个代码块.首先我尝试这样的代码:
public Form1(){初始化组件();SetStyle(ControlStyles.SupportsTransparentBackColor, true);this.BackColor = Color.Transparent;this.FormBorderStyle = FormBorderStyle.None;//this.WindowState = System.Windows.Forms.FormWindowState.Maximized;}
看起来像这张照片;
然后我找到了一些不同的代码并尝试了这个;
public Form1(){初始化组件();this.TransparencyKey = Color.White;this.BackColor = Color.White;this.FormBorderStyle = FormBorderStyle.None;this.WindowState = System.Windows.Forms.FormWindowState.Maximized;}
这看起来像这张照片;
您可以看到带有白色边框的徽标.我只想显示完全透明的 .png 徽标.我该怎么办?怎么能做到这一点?
这是我的 .png 格式的徽标图像;
您可以使用
PerPixelAlphaForm.cs
#region 使用指令使用系统;使用 System.Collections.Generic;使用 System.ComponentModel;使用 System.Data;使用 System.Drawing;使用 System.Text;使用 System.Windows.Forms;使用 System.Drawing.Imaging;使用 System.Runtime.InteropServices;#endregion命名空间 CSWinFormLayeredWindow{公共部分类 PerPixelAlphaForm :表单{公共 PerPixelAlphaForm(){this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;this.ShowInTaskbar = false;this.StartPosition = FormStartPosition.CenterScreen;this.Load += PerPixelAlphaForm_Load;}void PerPixelAlphaForm_Load(对象发送者,EventArgs e){this.TopMost = true;}受保护的覆盖 CreateParams CreateParams{得到{//将分层扩展样式(WS_EX_LAYERED)添加到此窗口.CreateParams createParams = base.CreateParams;如果(!设计模式)createParams.ExStyle |= WS_EX_LAYERED;返回 createParams;}}//////让 Windows 为我们拖动这个窗口(认为它点击标题///窗口栏)///</总结>///<param name=message"></param>protected override void WndProc(ref Message message){if (message.Msg == WM_NCHITTEST){//告诉 Windows 用户在标题栏(标题)message.Result = (IntPtr)HTCAPTION;}别的{base.WndProc(ref message);}}/////////</总结>///<param name=位图"></param>public void SelectBitmap(位图位图){SelectBitmap(位图, 255);}/////////</总结>/////////</param>//////指定要在整个源上使用的 alpha 透明度值///位图.SourceConstantAlpha 值与任何每像素结合///源位图中的 alpha 值.取值范围为 0 到 255.如果///您将 SourceConstantAlpha 设置为 0,则假定您的图像是///透明的.当您只想使用每像素 alpha 值时,请设置///将 SourceConstantAlpha 值设为 255(不透明).///</param>public void SelectBitmap(位图位图,int opacity){//此位图是否包含 alpha 通道?if (bitmap.PixelFormat != PixelFormat.Format32bppArgb){throw new ApplicationException(位图必须是 32bpp,带 alpha 通道.");}//获取设备上下文IntPtr screenDc = GetDC(IntPtr.Zero);IntPtr memDc = CreateCompatibleDC(screenDc);IntPtr hBitmap = IntPtr.Zero;IntPtr hOldBitmap = IntPtr.Zero;尝试{//获取新位图的句柄并将其选入当前//设备上下文.hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));hOldBitmap = SelectObject(memDc, hBitmap);//设置分层窗口更新的参数.尺寸 newSize = 新尺寸(bitmap.Width, bitmap.Height);点 sourceLocation = new Point(0, 0);Point newLocation = new Point(this.Left, this.Top);BLENDFUNCTION 混合 = 新的 BLENDFUNCTION();blend.BlendOp = AC_SRC_OVER;blend.BlendFlags = 0;blend.SourceConstantAlpha = (byte)opacity;blend.AlphaFormat = AC_SRC_ALPHA;//更新窗口.更新分层窗口(this.Handle,//分层窗口的句柄screenDc,//屏幕 DC 句柄ref newLocation,//分层窗口的新屏幕位置ref newSize,//分层窗口的新大小memDc,//分层窗口表面 DC 的句柄ref sourceLocation,//层在 DC 中的位置0,//分层窗口的颜色键ref blend,//分层窗口的透明度ULW_ALPHA//使用blend作为blend函数);}最后{//释放设备上下文.ReleaseDC(IntPtr.Zero, screenDc);if (hBitmap != IntPtr.Zero){SelectObject(memDc, hOldBitmap);删除对象(hBitmap);}删除DC(memDc);}}#region 本机方法和结构const Int32 WS_EX_LAYERED = 0x80000;const Int32 HTCAPTION = 0x02;const Int32 WM_NCHITTEST = 0x84;const Int32 ULW_ALPHA = 0x02;常量字节 AC_SRC_OVER = 0x00;常量字节 AC_SRC_ALPHA = 0x01;[结构布局(LayoutKind.Sequential)]结构点{公共 Int32 x;公共 Int32 y;公共点(Int32 x,Int32 y){ this.x = x;这.y = y;}}[结构布局(LayoutKind.Sequential)]结构体大小{公共 Int32 cx;公共 Int32 cy;公共尺寸(Int32 cx,Int32 cy){ this.cx = cx;this.cy = cy;}}[StructLayout(LayoutKind.Sequential, Pack = 1)]结构体 ARGB{公共字节蓝;公共字节绿色;公共字节红色;公共字节阿尔法;}[StructLayout(LayoutKind.Sequential, Pack = 1)]结构混合函数{公共字节 BlendOp;公共字节 BlendFlags;公共字节 SourceConstantAlpha;公共字节 AlphaFormat;}[DllImport(user32.dll", CharSet = CharSet.Auto, SetLastError = true)][返回:MarshalAs(UnmanagedType.Bool)]static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst,参考点pptDst,参考大小psize,IntPtr hdcSrc,参考点pprSrc,Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]静态外部 IntPtr CreateCompatibleDC(IntPtr hDC);[DllImport(user32.dll", CharSet = CharSet.Auto, SetLastError = true)]静态外部 IntPtr GetDC(IntPtr hWnd);[DllImport(user32.dll", CharSet = CharSet.Auto, SetLastError = true)]static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)][返回:MarshalAs(UnmanagedType.Bool)]static extern bool DeleteDC(IntPtr hdc);[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]静态外部 IntPtr SelectObject(IntPtr hDC, IntPtr hObject);[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)][返回:MarshalAs(UnmanagedType.Bool)]static extern bool DeleteObject(IntPtr hObject);#endregion}}
SplashScreen.cs
公共部分类 Form4 : CSWinFormLayeredWindow.PerPixelAlphaForm{公共 Form4(){初始化组件();this.SelectBitmap(Properties.Resources.splash);}}
注意
最初的答案是基于关闭双缓冲区并覆盖 OnPaintBackground
并在不调用基本方法的情况下绘制图像.答案有一个已知问题;虽然表单不动,但它运行良好,但如果表单正在移动或表单后面的窗口已更改,则窗口不会更新.您可以在修订版中看到以前的代码.当前完全基于 MSDN 代码的编辑没有任何已知问题.
When I tried from with transparent background, it's not completely transparent.I tried two code blocks for this issue. First i tried like this code:
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent;
this.FormBorderStyle = FormBorderStyle.None;
//this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
}
it look like this picture;
Then i found some different codes and tried ike this;
public Form1()
{
InitializeComponent();
this.TransparencyKey = Color.White;
this.BackColor = Color.White;
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
}
And this looks like this picture;
You can see logo with a white border. I want to show only .png Logo completely transparent. What should i do? How can do this?
Here is my Logo image as .png;
You can use Layered Windows:
Create layered window in Windows Forms
Here is some code from msdn code gallery which demonstrates creating Layered Windows in Windows Forms. It allows you to create a shaped splash screen and let you to move it by mouse.
Add PerPixelAlphaForm
to the project and then it's enough to inherit from this form and call its SelectBitmap
and pass your png to the method to create a layered window.
PerPixelAlphaForm.cs
#region Using directives
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
#endregion
namespace CSWinFormLayeredWindow
{
public partial class PerPixelAlphaForm : Form
{
public PerPixelAlphaForm()
{
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.CenterScreen;
this.Load += PerPixelAlphaForm_Load;
}
void PerPixelAlphaForm_Load(object sender, EventArgs e)
{
this.TopMost = true;
}
protected override CreateParams CreateParams
{
get
{
// Add the layered extended style (WS_EX_LAYERED) to this window.
CreateParams createParams = base.CreateParams;
if(!DesignMode)
createParams.ExStyle |= WS_EX_LAYERED;
return createParams;
}
}
/// <summary>
/// Let Windows drag this window for us (thinks its hitting the title
/// bar of the window)
/// </summary>
/// <param name="message"></param>
protected override void WndProc(ref Message message)
{
if (message.Msg == WM_NCHITTEST)
{
// Tell Windows that the user is on the title bar (caption)
message.Result = (IntPtr)HTCAPTION;
}
else
{
base.WndProc(ref message);
}
}
/// <summary>
///
/// </summary>
/// <param name="bitmap"></param>
public void SelectBitmap(Bitmap bitmap)
{
SelectBitmap(bitmap, 255);
}
/// <summary>
///
/// </summary>
/// <param name="bitmap">
///
/// </param>
/// <param name="opacity">
/// Specifies an alpha transparency value to be used on the entire source
/// bitmap. The SourceConstantAlpha value is combined with any per-pixel
/// alpha values in the source bitmap. The value ranges from 0 to 255. If
/// you set SourceConstantAlpha to 0, it is assumed that your image is
/// transparent. When you only want to use per-pixel alpha values, set
/// the SourceConstantAlpha value to 255 (opaque).
/// </param>
public void SelectBitmap(Bitmap bitmap, int opacity)
{
// Does this bitmap contain an alpha channel?
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
{
throw new ApplicationException("The bitmap must be 32bpp with alpha-channel.");
}
// Get device contexts
IntPtr screenDc = GetDC(IntPtr.Zero);
IntPtr memDc = CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr hOldBitmap = IntPtr.Zero;
try
{
// Get handle to the new bitmap and select it into the current
// device context.
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
hOldBitmap = SelectObject(memDc, hBitmap);
// Set parameters for layered window update.
Size newSize = new Size(bitmap.Width, bitmap.Height);
Point sourceLocation = new Point(0, 0);
Point newLocation = new Point(this.Left, this.Top);
BLENDFUNCTION blend = new BLENDFUNCTION();
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = (byte)opacity;
blend.AlphaFormat = AC_SRC_ALPHA;
// Update the window.
UpdateLayeredWindow(
this.Handle, // Handle to the layered window
screenDc, // Handle to the screen DC
ref newLocation, // New screen position of the layered window
ref newSize, // New size of the layered window
memDc, // Handle to the layered window surface DC
ref sourceLocation, // Location of the layer in the DC
0, // Color key of the layered window
ref blend, // Transparency of the layered window
ULW_ALPHA // Use blend as the blend function
);
}
finally
{
// Release device context.
ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero)
{
SelectObject(memDc, hOldBitmap);
DeleteObject(hBitmap);
}
DeleteDC(memDc);
}
}
#region Native Methods and Structures
const Int32 WS_EX_LAYERED = 0x80000;
const Int32 HTCAPTION = 0x02;
const Int32 WM_NCHITTEST = 0x84;
const Int32 ULW_ALPHA = 0x02;
const byte AC_SRC_OVER = 0x00;
const byte AC_SRC_ALPHA = 0x01;
[StructLayout(LayoutKind.Sequential)]
struct Point
{
public Int32 x;
public Int32 y;
public Point(Int32 x, Int32 y)
{ this.x = x; this.y = y; }
}
[StructLayout(LayoutKind.Sequential)]
struct Size
{
public Int32 cx;
public Int32 cy;
public Size(Int32 cx, Int32 cy)
{ this.cx = cx; this.cy = cy; }
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ARGB
{
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct BLENDFUNCTION
{
public byte BlendOp;
public byte BlendFlags;
public byte SourceConstantAlpha;
public byte AlphaFormat;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst,
ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc,
Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DeleteObject(IntPtr hObject);
#endregion
}
}
SplashScreen.cs
public partial class Form4 : CSWinFormLayeredWindow.PerPixelAlphaForm
{
public Form4()
{
InitializeComponent();
this.SelectBitmap(Properties.Resources.splash);
}
}
Note
The original answer was based on turning double buffer off and overriding OnPaintBackground
and drawing the image without calling base method. The answer had a known issue; while the form was moveless it was working well but if form was moving or the window behind the form was changed the window was not updating. You can see previous code in revisions. The current edit which is completely based on an MSDN code doesn't have any known issue.
这篇关于C# Windows 窗体透明背景图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!