从 Control Visual 创建具有透明背景的图标
Create Icon with transparent background from Control Visual
我正在使用 HardCodet.NotifyIcon.Wpf 在系统托盘中显示状态图标。我需要更改图标,所以我不能为图标使用资源文件。我有一个在我的应用程序中绘制的用户控件,我想使用该控件的视觉效果作为我的托盘图标的来源。除了托盘上的图标有黑色背景而不是透明背景外,我一切正常。如果我画一个矩形,颜色就会出现。我尝试将矩形颜色设置为透明,但结果是黑色。我得到的最接近的解决方法是尝试绘制背景以匹配任务栏颜色。我找不到获取任务栏颜色的方法,window 标题颜色有点浅(在下面的示例代码中使用)。这是到目前为止我使用来自各种搜索的片段获得的代码。
//can't figure out how to render the MsgNotifyIcon visual as an icon with a tranparent background.
RenderTargetBitmap rtb = new RenderTargetBitmap((int)MsgNotifyIcon.ActualWidth, (int)MsgNotifyIcon.ActualHeight, 96, 96, PixelFormats.Pbgra32);
VisualBrush sourceBrush = new VisualBrush(MsgNotifyIcon);
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
var rect = new Rect(0, 0, MsgNotifyIcon.RenderSize.Width, MsgNotifyIcon.RenderSize.Height);
int argbColor = (int)Microsoft.Win32.Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", "ColorizationColor", null);
var color = System.Drawing.Color.FromArgb(argbColor);
Color taskbarcolor = System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);
using (drawingContext)
{
drawingContext.PushTransform(new ScaleTransform(1, 1));
drawingContext.DrawRectangle(new SolidColorBrush(taskbarcolor), null, rect);
drawingContext.DrawRectangle(sourceBrush, null, new Rect(new System.Windows.Point(0, 0), new System.Windows.Point(MsgNotifyIcon.ActualWidth, MsgNotifyIcon.ActualHeight)));
}
rtb.Render(drawingVisual);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
MemoryStream stream = new MemoryStream();
encoder.Save(stream);
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(stream);
MsgNotifyTBIcon.Icon = System.Drawing.Icon.FromHandle(bmp.GetHicon()) ;
MsgNotifyTBIcon.Visibility = Visibility.Visible;
有没有办法做到这一点?
This similar question didn't have any answers that worked in my situation.
BmpBitmapEncoder
不支持透明度。使用 PngBitmapEncoder
代替:
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
...
我正在使用 HardCodet.NotifyIcon.Wpf 在系统托盘中显示状态图标。我需要更改图标,所以我不能为图标使用资源文件。我有一个在我的应用程序中绘制的用户控件,我想使用该控件的视觉效果作为我的托盘图标的来源。除了托盘上的图标有黑色背景而不是透明背景外,我一切正常。如果我画一个矩形,颜色就会出现。我尝试将矩形颜色设置为透明,但结果是黑色。我得到的最接近的解决方法是尝试绘制背景以匹配任务栏颜色。我找不到获取任务栏颜色的方法,window 标题颜色有点浅(在下面的示例代码中使用)。这是到目前为止我使用来自各种搜索的片段获得的代码。
//can't figure out how to render the MsgNotifyIcon visual as an icon with a tranparent background.
RenderTargetBitmap rtb = new RenderTargetBitmap((int)MsgNotifyIcon.ActualWidth, (int)MsgNotifyIcon.ActualHeight, 96, 96, PixelFormats.Pbgra32);
VisualBrush sourceBrush = new VisualBrush(MsgNotifyIcon);
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
var rect = new Rect(0, 0, MsgNotifyIcon.RenderSize.Width, MsgNotifyIcon.RenderSize.Height);
int argbColor = (int)Microsoft.Win32.Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", "ColorizationColor", null);
var color = System.Drawing.Color.FromArgb(argbColor);
Color taskbarcolor = System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);
using (drawingContext)
{
drawingContext.PushTransform(new ScaleTransform(1, 1));
drawingContext.DrawRectangle(new SolidColorBrush(taskbarcolor), null, rect);
drawingContext.DrawRectangle(sourceBrush, null, new Rect(new System.Windows.Point(0, 0), new System.Windows.Point(MsgNotifyIcon.ActualWidth, MsgNotifyIcon.ActualHeight)));
}
rtb.Render(drawingVisual);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
MemoryStream stream = new MemoryStream();
encoder.Save(stream);
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(stream);
MsgNotifyTBIcon.Icon = System.Drawing.Icon.FromHandle(bmp.GetHicon()) ;
MsgNotifyTBIcon.Visibility = Visibility.Visible;
有没有办法做到这一点?
This similar question didn't have any answers that worked in my situation.
BmpBitmapEncoder
不支持透明度。使用 PngBitmapEncoder
代替:
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
...