原文出自:C# 实现真正的透明控件(Windows桌面程序)_yangshengchuan的博客-CSDN博客_c# 控件透明

修改了一点bug和方式,现在可以根据任意指定颜色镂空,还可以一次性镂空多个颜色

使用方法:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace UControlTran
{public partial class UserControl1 : UserControl{/************************************************************************************************//******** 构造函数里画图用的文本text必须跟 OnPaint 里面的 text 一模一样,否则文字就错位了*********//******** 自己修改一下构造函数,可以把text作为参数传入,然后保存,OnPaint 直接调用保存的   *********//************************************************************************************************/private const TextFormatFlags textFormatFlags = TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix | TextFormatFlags.PreserveGraphicsClipping;public UserControl1(){InitializeComponent();var bit = new Bitmap(1, 1);var g = Graphics.FromImage(bit);var text = "关于其他双缓存,半透明,请参考其他相关知识";Size size = TextRenderer.MeasureText(g, text, this.Font, new Size(-1, 0), textFormatFlags);TextSize = size;//长宽要保留下来,下面 OnPaint 需要用到g.Dispose();var bitmap = new Bitmap(size.Width, size.Height);g = Graphics.FromImage(bitmap);//首先要明白,这里用text来画,并不是就把text画到控件上了//而是参照图片画一个跟文字形状一样的图片!!!!!!!!!!!!!!//所以要在 OnPaint 重新画文字g.DrawString(text, this.Font, Brushes.Red,-1,0);//随手用 text 画了一个测试图片g.Dispose();Region = APub.ImageToRegionPx(bitmap, Color.FromArgb(0, 0, 0, 0));//将所有透明的区域全部镂空.这样控件里面就不会显示上面 text 内容以外的区域bitmap.Dispose();}public Size TextSize { get; set; }/// <summary>/// 重写OnPaint方法/// </summary>/// <param name="e"></param>protected override void OnPaint(PaintEventArgs e){var text = "关于其他双缓存,半透明,请参考其他相关知识";base.OnPaint(e);var g = e.Graphics;var brush = new SolidBrush(Color.Red);//为什么要在这里再画一次文本,是因为构造函数里面的方法只是以文字的像素/点阵信息为矩阵,画了一个跟文字一样的控件出来,//所以颜色是黑色的,那么要实现自己的颜色就必须真正的把颜色文字绘制到控件.g.DrawString(text, this.Font, brush, -1, 0);brush.Dispose();g.Dispose();Size = TextSize;}protected override void OnMouseHover(EventArgs e){this.Cursor = Cursors.SizeAll;base.OnMouseHover(e);}protected override void OnMouseLeave(EventArgs e){this.Cursor = Cursors.Default;base.OnMouseLeave(e);}}
}

//镂空方法

/// <summary>/// 从图片中获取除指定颜色以外的色块区域图.同时对png透明兼容./// 这个要在自定义控件/// </summary>/// <param name="Picture">取其区域的图片。</param>/// <param name="TransparentColor">要镂空的颜色,必须是ARGB,必须带A,/// 因为如果是黑色,rgb=0,0,0,如果没有A通道,黑色就直接被过滤掉了.所以如果要过滤png图片的透明层,就要填Color.FromArgb(0, 0, 0,0)</param>/// <returns>图片中非透明色部分的区域</returns>public unsafe static Region ImageToRegionPx(Image Picture, Color TransparentColor){return ImageToRegionPx(Picture, new List<Color>() { TransparentColor });}/// <summary>/// 从图片中获取除指定颜色以外的色块区域图.同时对png透明兼容/// </summary>/// <param name="Picture">取其区域的图片。</param>/// <param name="keyColors">要镂空的颜色,必须是ARGB,必须带A,/// 因为如果是黑色,rgb=0,0,0,如果没有A通道,黑色就直接被过滤掉了.所以如果要过滤png图片的透明层,就要填Color.FromArgb(0, 0, 0,0)</param>/// <returns>图片中非透明色部分的区域</returns>public unsafe static Region ImageToRegionPx(Image Picture, List<Color> keyColors){if (Picture == null) return null;Region rgn = new Region();rgn.MakeEmpty();Bitmap bitmap = null;if (Picture.GetType() != typeof(Bitmap))bitmap = new Bitmap(Picture);elsebitmap = (Bitmap)Picture;int width = bitmap.Width;int height = bitmap.Height;BitmapData bmData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);byte* p = (byte*)bmData.Scan0;int offset = bmData.Stride - width * 4;Rectangle curRect = new Rectangle();curRect.Height = 1;int start = -1;// 行座标 ( Y ) for (int Y = 0; Y < height; Y++){// 列座标 ( X ) for (int X = 0; X < width; X++){///如果像素色彩不是列表中要排除的颜色///p[3] > 0 如果不透明度是0,就说明是空白像素,强制排除if (start == -1 && p[3] > 0 && keyColors.All(argb => p[3] > argb.A || p[2] != argb.R || p[1] != argb.G || p[0] != argb.B)){start = X;                            //记录这个点curRect.X = X;curRect.Y = Y;}//如果当前像素是要排除的颜色,将 start 要复位else if (start > -1 && keyColors.Any(argb => p[3] <= argb.A && p[2] == argb.R && p[1] == argb.G && p[0] == argb.B)){curRect.Width = X - curRect.X;rgn.Union(curRect);start = -1;}if (X == width - 1 && start > -1)        //如果 之前的点是不透明 且 是最后一个点{curRect.Width = X - curRect.X;rgn.Union(curRect);start = -1;}p += 4;//下一个内存地址}p += offset;}bitmap.UnlockBits(bmData);bitmap.Dispose();return rgn;}

C# 控件透明背景(winform)相关推荐

  1. MFC学习之 对话框设置背景颜色及控件透明的方法

    对话框设置背景色之后控件不透明的问题. 1.对话框设置背景色: 方法1:(用OnPaint()) 在Dlg.h中:声明 afx_msg void OnPaint(); HICON m_hIcon; 在 ...

  2. html控件透明与背景透明

    html控件透明与背景透明 如何实现一个控件的半透明效果? IE中关于半透明和透明控件的一些说明 .大家在有些时候希望自己做的控件是半透明或透明的,就像半透明的窗体一样,我经过一段时间的查询,发现这个 ...

  3. MFC/WTL 设置背景图和控件透明的方法

    1.MFC 对话框设置背景图 方法一: 1>资源中导入一张bitmap图,如命名为 IDB_BITMAP1 2>对话框中添加一个 Picture Control,属性设置 Type 改为B ...

  4. C# 设置label(标签)控件的背景颜色为透明

    有时候,我们需要将控件的背景颜色设定为透明,比如说label(标签)控件.那么,如何将控件的背景颜色设定为透明?是不是只要将控件的BackColor属性设为Transparent(透明)就可以了呢?答 ...

  5. C#学习笔记:设置label(标签)控件的背景颜色为透明

    有时候,我们需要将控件的背景颜色设定为透明,比如说label(标签)控件.那么,如何将控件的背景颜色设定为透明?是不是只要将控件的BackColor属性设为Transparent(透明)就可以了呢?答 ...

  6. C#设置label(标签)控件的背景颜色为透明

    C#学习笔记:设置label(标签)控件的背景颜色为透明 有时候,我们需要将控件的背景颜色设定为透明,比如说label(标签)控件.那么,如何将控件的背景颜色设定为透明?是不是只要将控件的BackCo ...

  7. C# Winform的panel控件添加背景图片后窗体闪烁问题解决办法

    C# Winform的panel控件添加背景图片后窗体闪烁问题解决办法 参考文章: (1)C# Winform的panel控件添加背景图片后窗体闪烁问题解决办法 (2)https://www.cnbl ...

  8. QtUI设计:设置控件透明

    QT设置按钮控件透明: 代码: //设置按钮 背景 前景this->ui->ShowCvRGB->setStyleSheet(QString("color:rgba(255 ...

  9. QT窗口:透明与半透明、不规则异形窗口、控件透明与半透明、不规则异形按钮

    目录 1.不规则异形窗口和控件的代码原理 2.主窗口全透明 3.主窗口半透明(以白里透红为例) 4.不规则异形窗口 5.不规则异形按钮 6.使用样式表实现透明与半透明 1.不规则异形窗口和控件的代码原 ...

  10. c#模拟看板控件_ComponentOne for Winform

    WinForm UI 控件集 WinForm UI 控件集 快速创建直观.现代的 Windows 窗体应用程序 ComponentOne for WinForm 控件集为 WinForm 应用程序提供 ...

最新文章

  1. html文字绕图文字置顶,如何实现html文字绕排
  2. [Linux]Linux下网络配置文件总结(转)
  3. python中不区分大小写语句怎么写_Python中的标识符不区分大小写。( )_学小易找答案...
  4. QT的QStandardItemModel类的使用
  5. Main函数中的argc和argv应用举例
  6. Java 8发布一年后,IDE和编译器尚未完全就绪
  7. NuGet的使用、部署、搭建私有服务
  8. 解密 TCP/IP!
  9. 怎样使用python画复杂函数_在python中绘制复杂的函数?
  10. 解决git clone时报错fatal: HTTP request failed
  11. 如果你的下属不服从你得管理,你会怎么办?
  12. 第三版全球干旱指数和潜在蒸散数据发布
  13. php 0改成百 千_php 根据啊拉伯数字转变成大写中文数字
  14. 二元多项式基本运算 选择合适的存储结构表示二元多项式,并实现基本的加减运算 要求: 1)二元多项式的输入采用如下方式进行键盘输入 (5y^2+7)x^4 + (3y^4+2y+9)x^2 + (2y
  15. EF 正在运行转换: System.Reflection.TargetInvocationException: 调用的目标发生了异常。
  16. Janus源码分析(4)——信令交互过程
  17. 简单四步抓取腾讯视频MP4文件
  18. 蓝牙nrf52832的架构和开发
  19. 万字干货,Python语法大合集,一篇文章带你入门
  20. Opencv+Zbar二维码识别(标准条形码/二维码识别)

热门文章

  1. 脚本小子_python正则表达式
  2. 徐耀赐:道路安全——交通安全会议整理稿(1)
  3. pythonturtle魔法阵_python turtle 库绘制简单魔法阵
  4. 23_STM32调试和下载:SW配置
  5. 爱加密,梆梆,360加固初比较
  6. 针对VMware安装Win10需要安装.NET Framework 3.5常见的0x800F0906、0x800F081F错误解决办法
  7. How to Become a Straight-A student
  8. 如何用html语言制作圆角矩形,webGL中圆角矩形的绘制
  9. win10计算机删除了怎么恢复,Win10系统删除的文件怎么恢复?
  10. 【洛谷】P2689 东南西北(dfs|贪心)