在Windows窗体中如何使用透明图片和标签

本文介绍如何在Windows窗体中实现图片和标签的透明效果。通过使用GDI+和自定义控件,可以轻松地让图片和文字变得透明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨天一朋友问到Windows窗体中图片透明的问题,刚上网看看了,在CodeProject上看到了这篇文章,觉得写的不错,再者自己一直想学学翻译技术文章,所以就将其翻译成中文,希望能给大家带来点帮助。

申明:初次翻译此类文章,属处女作,难免有不对之处,欢迎大家拍砖指教!^_^

OK,开始正文……

 

引言——没有透明度的Windows窗体

如果你制作一些包括图片和标签的复杂的窗体,你可能会发现:Windows窗体不支持真正的透明。你可能撕裂了你的头皮了——但仍没有解决!

即使,你在图片或标签的BackColor属性上使用了透明值来控制,但结果是:你仍然发现不能使其透明。那么,这是为什么呢?为什么明明设置成透明了,却没有透明呢?到底都发生了些什么呢?

实际上,当你在BackColor属性上设置透明值来控制的时候,只是将其背景设置成与父窗体——Windows窗体一样的背景而已,并没有真正的透明!所以当它们重叠放在一起的时候你仍然会发现它们相互之间并没有透明,如下图所示:

 

 

在本文中,我们将向你展示一个简单的方法来使得标签的后面图片作为背景,并如何使图片和文字真正的变成透明。

 

    如何制作透明标签

    使图片作为背景而标签或文字在其前面进行显示是否真的很容易?

    在下面,我们将讲解如何使标签的背景透明。

 

    有二种方法,你可以使用它来很标签的背景透明(其实有更多的方法可以做到这一点,但是我们只去谈论较为简单些的):

      1.  通过设置PanelBackGroundImage属性,并且将标签Lable放到它的里面

      2.  Lable的父窗体设置成PictureBoxlabel.Parent = pictureBox

   这样,我们将不需要编写任何的代码,并且我们可以在设计器里马上看到其透明的效果:

 

 

 

 

首先,拖一个Panel控件到窗体中,并将其BackgroundImage属性设置成一张你希望看到的图片来作为背景(你可以使用其BackgroundImageLayout来控制其排列的方式)。

 

最后,添加一个Lable标签,并将其BackColor属性设置成透明的(Web选项卡的第一个选项)。最终的结果应该是类似下面的图片:

这样,我们就可以将标签设成透明了,但图片仍然没有透明(上面的二张图片之间仍然没有实现相互透明)!不要担心,下面我们就来讨论它们透明的问题。

 

   使用GDI+来绘制图片的透明度

使绘制的图像真正的透明有一点麻烦,因为我们不能使用默认的控件来配置.NET中的 Windows窗体。

 

对于更为复杂的图像和图形处理,我们可以使用GDI + ,它是一个图形设备接口(你可以在System.Drawing命名空间中找到它)。

 

我们会做的是建立一个通用的控件,我们就可以任意继承它并提取图片和文字了。这可以在本项目的源代码中看到,但如果你想了解它如何工作,请继续住下阅读。

 

   绘制通用图像控件

首先,创建一个继承于Panel的新类,称其为DrawingArea 。这个类有一个抽象的OnDraw方法并且我们在子类中要对此方法进行重写,所以我们还需要将DrawingArea类声名为抽象类。

此外,我们还会添加一个Graphics图形对象来绘制图片。你应该像这样:

 


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

/// <summary>
///自定义绘制图形和文字的透明度
///继承DrawingArea和覆盖OnDraw方法。
/// </summary>

abstract public class DrawingArea : Panel
{
    
/// <summary>
    
/// 在OnDraw方法中使用此对象
    
/// </summary>

    protected Graphics graphics;

    
/// <summary>
    
/// 在子类中应该要重写此方法
    
/// </summary>

    abstract protected void OnDraw();
}

 

    我们需要确保我们的控件背景透明度进行正确的处理。为此,我们需要重写CreateParams属性,以确保其风格与控件实例的正确(感谢Bob Powell的提示)。

 

 


protected override CreateParams CreateParams
    
{
        
get
        
{
            CreateParams cp 
= base.CreateParams;
            cp.ExStyle 
|= 0x00000020//WS_EX_TRANSPARENT

            
return cp;
        }

}

 

 

现在,只有两件事情是必须的。

首先,我们必须确保背景不会被绘制出来。我们要做到这一点,首先要重写OnPaintBackground方法。

 

第二件事是需重写OnPaint方法。这使我们能够确定程序在将我们的控制下进行绘制。

  


protected override void OnPaintBackground(PaintEventArgs pevent)
    
{
        
// 不要绘制背景
    }


    
protected override void OnPaint(PaintEventArgs e)
    

        
this.graphics = e.Graphics;

        
// 设置显示的效果质量属性
        this.graphics.TextRenderingHint = 
            System.Drawing.Text.TextRenderingHint.AntiAlias;
        
this.graphics.InterpolationMode = 
            System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
        
this.graphics.PixelOffsetMode = 
            System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
        
this.graphics.SmoothingMode = 
            System.Drawing.Drawing2D.SmoothingMode.HighQuality;

        OnDraw();
    }

 

 

我还定义了一个DrawText方法以及一些变量,以便更容易的写文字。我在这里不进行讲解,但你可以在项目的源代码中找到它。

 

使用控制绘制图片和文字与透明

现在,我们如何使用这个控件吗?我们需要一个新的类来继承DrawingArea 。这是非常简单容易的事情。在这里,我提供了一个例子:

 


class BroculosDrawing : DrawingArea
{
    
protected override void OnDraw()
    
{
        
// 获取资源
        Image broculoImage = global::WindowsApplication1.Properties.Resources.broculo;

        
// 设置图片的属性
        int width = broculoImage.Size.Width;
        
int height = broculoImage.Size.Height;
        Rectangle big 
= new Rectangle(00, width, height);
        Rectangle small 
= new Rectangle(5050, (int)(0.75 * width),
                (
int)(0.75 * height));

        
// 绘制二张图片
        this.graphics.DrawImage(broculoImage, big);
        
this.graphics.DrawImage(broculoImage, small);

        
// 设置文字的属性,并将其绘制出来
        float fontSize = 8.25f;
        Point textPosition 
= new Point(50100);
        DrawText(
"http://www.broculos.net""Microsoft Sans Serif", fontSize
            , FontStyle.Underline, Brushes.Blue, textPosition);
    }

}

 

这将使用两个图片和一些文字(类似于之前的) ,但现在是真正透明度!

 

我们可以像其它控件一样使用这个控件。对其进行编译,这个新的控件应该会出现在工具箱中。拖动它到新的窗体中!你便可以看到如下图所示的结果:

 

 

 

 

      结论

现在你知道如何利用图像的透明度了吧。最大的缺点是它在.NET中内置的Windows窗体控件上不太容易使用。默认的控件在使用更先进的图像操作时是非常有限的,所以我们使用GDI +来克服这一点。

 

应用这方面的知识并做更多一点的工作,应该有可能做出TransparentPictureBox 。希望它能给你带来帮助。

 

 

原文地址:http://www.codeproject.com/KB/dotnet/transparent_controls_net.aspx

 本文源码下载 

作者: asidy
出处: http://asidy.cnblogs.com
版权说明:本文版权归作者、博客园及优快云共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
1. Custom Dialog Android支持自定义窗口的风格: 1)首先在资源里面建立style的value; example: <style name="Theme.CustomDialog" parent="android:style/Theme.Dialog"> <item name="android:windowBackground">@drawable/filled_box</item> </style> drawable/filled_box.xml <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#f0600000"/> <stroke android:width="3dp" color="#ffff8080"/> <corners android:radius="3dp" /> <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" /> </shape> PS:关于Styles的学习,可以参见:http://code.google.com/android/reference/available-resources.html#stylesandthemes 2)设置当前activity的属性,两种方式:1.在manifest文件中给指定的activity增加属性 android:theme="@android:style/Theme.CustomDialog"。2.在程序中增加语句setTheme(R.style.Theme_CustomDialog); PS1:如果只是将Acticity显示为默认的Dialog, 跳过第一步,只需要在manifest文中增加属性:android:theme="@android:style/Theme.Dialog"或者在程序中增加setTheme(android.R.style.Theme_Dialog). PS2:其他创建Dialog的方法:创建app.Dialog类或者创建app.AlertDialog类。 Next Study:能不能在Activity已经打开以后动态修改当前Activity的风格? 在测试中发现,在onCreate()事件中增加setTheme(),必须在setContentView()之前,否则指定的Style不能生效 2.Custom Title Android除了可以为指定的Activity设置显示风格,此外也可以为指定的Activity设置一些特效,比如自定义Title,没有Title的Activity或者增加一个ICON等。 有意思的一点是,这些特效并不是你想设置的时候就行设置,你需要在Activity显示之前向系统申请要显示的特效,这样才能在下面的程序中为这些特效进行设置。(这样是不是多此一举有待研究) 为一个Activity设置自定义Title的流程: 1)为自定义的Title建立一个layout(custom_title_1.xml) <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/screen" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:id="@+id/left_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:text="Left" /> <TextView android:id="@+id/right_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="Right" /> </RelativeLayout> 关于为什么采用RelativeLayout,可以参见:http://code.google.com/android/devel/ui/layout.html 2)为activity设定自定义Title特效并指定Title的layout: 在onCreate()事件中增加: requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.custom_title); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_1); 这三条语句的次序不能颠倒,依次为申请特效,创建view,设置特效属性。其中requestWindowFeature等价于getWindow().requestFeature() 3)在需要修改Title的地方,获取left_text或者right_text进行设置即可。 Next Study:Activity的其他显示特效 Window还有其他一些feature,比如FEATURE_CONTEXT_MENU,FEATURE_NO_TITLE,FEATURE_LEFT_ICON等,有待继续学习研究。 Translucent Android为透明效果提供了内置的Theme: android:style/Theme.Translucent,只需要把当前的activity的theme设置为这个Theme就可以达到完全透明的效果。 如果要半透明的话,可以增加一个继承该Theme的style即可,实现如下: <style name="Theme.Translucent" parent="android:style/Theme.Translucent"> <item name="android:windowBackground">@drawable/translucent_background</item> <item name="android:colorForeground">#fff</item> </style> <drawable name="translucent_background">#e0000000</drawable> 此外API Demo中提供了另一个实例,不用继承内置的Theme,可以自己完全创建一个新的style,实现透明效果,同时可以加一些其他特效,比如模糊化等,但我试了半天也没有搞定,完全复制代码,也没有出现这个效果,这个现在可能不是很重要的东西,等以后有时间再研究补充吧。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值