昨天一朋友问到Windows窗体中图片透明的问题刚上网看看了在CodeProject上看到了这篇文章觉得写的不错再者自己一直想学学翻译技术文章所以就将其翻译成了中文希望能给大家带来点帮助 申明初次翻译此类文章属处女作难免有不对之处欢迎大家拍砖指教!^_^ OK开始正文…… 引言——没有透明度的Windows窗体 如果你制作一些包括图片和标签的复杂的窗体你可能会发现Windows窗体不支持真正的透明你可能撕裂了你的头皮了——但仍没有解决! 即使你在图片或标签的BackColor属性上使用了透明值来控制但结果是你仍然发现不能使其透明那么这是为什么呢?为什么明明设置成透明了却没有透明呢?到底都发生了些什么呢? 实际上当你在BackColor属性上设置透明值来控制的时候只是将其背景设置成与父窗体——Windows窗体一样的背景而已并没有真正的透明!所以当它们重叠放在一起的时候你仍然会发现它们相互之间并没有透明如下图所示 在本文中我们将向你展示一个简单的方法来使得标签的后面图片作为背景并如何使图片和文字真正的变成透明 如何制作透明标签 使图片作为背景而标签或文字在其前面进行显示是否真的很容易? 在下面我们将讲解如何使标签的背景透明 有二种方法你可以使用它来很标签的背景透明(其实有更多的方法可以做到这一点但是我们只去谈论较为简单些的) . 通过设置Panel的BackGroundImage属性并且将标签Lable放到它的里面 . 将Lable的父窗体设置成PictureBox(labelParent = pictureBox) 这样我们将不需要编写任何的代码并且我们可以在设计器里马上看到其透明的效果 首先拖一个Panel控件到窗体中并将其BackgroundImage属性设置成一张你希望看到的图片来作为背景(你可以使用其BackgroundImageLayout来控制其排列的方式) 最后添加一个Lable标签并将其BackColor属性设置成透明的(Web选项卡的第一个选项)最终的结果应该是类似下面的图片 这样我们就可以将标签设成透明了但图片仍然没有透明(上面的二张图片之间仍然没有实现相互透明)!不要担心下面我们就来讨论它们透明的问题 使用GDI+来绘制图片的透明度 使绘制的图像真正的透明有一点麻烦因为我们不能使用默认的控件来配置NET中的 Windows窗体 对于更为复杂的图像和图形处理我们可以使用GDI + 它是一个图形设备接口(你可以在SystemDrawing命名空间中找到它) 我们会做的是建立一个通用的控件我们就可以任意继承它并提取图片和文字了这可以在本项目的源代码中看到但如果你想了解它如何工作请继续住下阅读 绘制通用图像控件 首先创建一个继承于Panel的新类称其为DrawingArea 这个类有一个抽象的OnDraw方法并且我们在子类中要对此方法进行重写所以我们还需要将DrawingArea类声名为抽象类 此外我们还会添加一个Graphics图形对象来绘制图片你应该像这样 using System; using SystemDrawing; using SystemWindowsForms; using SystemDrawingDrawingD; /// <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 = baseCreateParams; cpExStyle |= x; //WS_EX_TRANSPARENT return cp; } } 现在只有两件事情是必须的 首先我们必须确保背景不会被绘制出来我们要做到这一点 首先要重写OnPaintBackground方法 第二件事是需重写OnPaint方法这使我们能够确定程序在将我们的控制下进行绘制 protected override void OnPaintBackground(PaintEventArgs pevent) { // 不要绘制背景 } protected override void OnPaint(PaintEventArgs e) { thisgraphics = eGraphics; // 设置显示的效果质量属性 thisgraphicsTextRenderingHint = SystemDrawingTextTextRenderingHintAntiAlias; thisgraphicsInterpolationMode = SystemDrawingDrawingDInterpolationModeHighQualityBilinear; thisgraphicsPixelOffsetMode = SystemDrawingDrawingDPixelOffsetModeHighQuality; thisgraphicsSmoothingMode = SystemDrawingDrawingDSmoothingModeHighQuality; OnDraw(); } 我还定义了一个DrawText方法以及一些变量以便更容易的写文字我在这里不进行讲解但你可以在项目的源代码中找到它 使用控制绘制图片和文字与透明 现在我们如何使用这个控件吗?我们需要一个新的类来继承DrawingArea 这是非常简单容易的事情在这里我提供了一个例子 class BroculosDrawing : DrawingArea { protected override void OnDraw() { // 获取资源 Image broculoImage = global::WindowsApplicationPropertiesResourcesbroculo; // 设置图片的属性 int width = broculoImageSizeWidth; int height = broculoImageSizeHeight; Rectangle big = new Rectangle( width height); Rectangle small = new Rectangle( (int)( * width) (int)( * height)); // 绘制二张图片 thisgraphicsDrawImage(broculoImage big); thisgraphicsDrawImage(broculoImage small); // 设置文字的属性并将其绘制出来 float fontSize = f; Point textPosition = new Point( ); DrawText( Microsoft Sans Serif fontSize FontStyleUnderline BrushesBlue textPosition); } } 这将使用两个图片和一些文字(类似于之前的) 但现在是真正透明度! 我们可以像其它控件一样使用这个控件对其进行编译这个新的控件应该会出现在工具箱中拖动它到新的窗体中!你便可以看到如下图所示的结果 结论 现在你知道如何利用图像的透明度了吧最大的缺点是它在NET中内置的Windows窗体控件上不太容易使用默认的控件在使用更先进的图像操作时是非常有限的所以我们使用GDI +来克服这一点 应用这方面的知识并做更多一点的工作应该有可能做出TransparentPictureBox 希望它能给你带来帮助 原文地址_controls_netaspx 本文源码下载 作者asidy 出处 版权说明本文版权归作者博客园及CSDN共有欢迎转载但未经作者同意必须保留此段声明且在文章页面明显位置给出原文连接否则保留追究法律责任的权利 |