向图标添加叠加层时的透明度问题

发布于 2024-11-29 12:26:28 字数 1558 浏览 1 评论 0原文

我有一个 .ico 文件,其中包含一个 .png 文件,其中包含我想要应用于图标的覆盖层。我在这方面非常缺乏经验,所以设法从互联网上获取一些代码,直到我有了一些几乎可以工作的东西。

问题是透明度丢失并被白色取代。

另外,我认为颜色范围减少了。我添加了一些调试代码(已注释掉)以分两个阶段保存图标。当我在VS 2010的第一阶段编辑它时,调色板有16种颜色,stage1.ico有更多。

似乎是 Icon.FromHandle 导致了问题。下面的函数采用两个 ImageSource 参数。第一个来自 .ico 文件,第二个来自 .png 文件(覆盖)。

我应该做什么呢?

功能 -

private static Icon Render(ImageSource baseImage, ImageSource overlay)
{
  int iconSize = 32;

  RenderTargetBitmap renderBitmap
    = new RenderTargetBitmap(iconSize,
    iconSize,
    96, 96,
    PixelFormats.Pbgra32);

  DrawingVisual visual = new DrawingVisual();
  using (DrawingContext context = visual.RenderOpen())
  {
    context.DrawImage(baseImage, new System.Windows.Rect(0, 0, iconSize, iconSize));
    context.DrawImage(overlay, new System.Windows.Rect(0, 0, iconSize, iconSize));
    context.Close();
    renderBitmap.Render(visual);
  }
  BmpBitmapEncoder encoder = new BmpBitmapEncoder();
  encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
  MemoryStream stream = new MemoryStream();
  encoder.Save(stream); 

  Bitmap bmp = new Bitmap(stream);
  //bmp.Save("c:\\tmp\\stage1.ico"); // save what we have here
  IntPtr Hicon = bmp.GetHicon();
  Icon icon = Icon.FromHandle(Hicon);
  // Looking at stage2.ico gives a different version to stage1.ico
  //using (var fs = new FileStream("c:\\tmp\\stage2.ico", FileMode.Create, FileAccess.Write, FileShare.Delete))
  //{
    //icon.Save(fs);
  //}
  return icon;
}

I've got an .ico file with a .png file that has an overlay I want to apply to the icon. I'm very inexperienced in this so managed to get bits of code off the internet until I had something that almost works.

The problem is that the transparency is lost and replaced with white.

Also, I think the range of colours is reduced. I added some debug code (commented out) to save the icon at 2 stages. When I edit it at the first stage in VS 2010, the colour pallete has 16 colours, stage1.ico has many more.

Seems to be the Icon.FromHandle causing the problems. The function below takes two ImageSource parameters. The first comes from the .ico file and the second from the .png file (overlay).

What should I be doing instead?

Function -

private static Icon Render(ImageSource baseImage, ImageSource overlay)
{
  int iconSize = 32;

  RenderTargetBitmap renderBitmap
    = new RenderTargetBitmap(iconSize,
    iconSize,
    96, 96,
    PixelFormats.Pbgra32);

  DrawingVisual visual = new DrawingVisual();
  using (DrawingContext context = visual.RenderOpen())
  {
    context.DrawImage(baseImage, new System.Windows.Rect(0, 0, iconSize, iconSize));
    context.DrawImage(overlay, new System.Windows.Rect(0, 0, iconSize, iconSize));
    context.Close();
    renderBitmap.Render(visual);
  }
  BmpBitmapEncoder encoder = new BmpBitmapEncoder();
  encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
  MemoryStream stream = new MemoryStream();
  encoder.Save(stream); 

  Bitmap bmp = new Bitmap(stream);
  //bmp.Save("c:\\tmp\\stage1.ico"); // save what we have here
  IntPtr Hicon = bmp.GetHicon();
  Icon icon = Icon.FromHandle(Hicon);
  // Looking at stage2.ico gives a different version to stage1.ico
  //using (var fs = new FileStream("c:\\tmp\\stage2.ico", FileMode.Create, FileAccess.Write, FileShare.Delete))
  //{
    //icon.Save(fs);
  //}
  return icon;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

撕心裂肺的伤痛 2024-12-06 12:26:28

我能够使用下面的代码动态创建一个具有透明度的图标,用作覆盖图标。对于我的程序,我想要一个显示排队的新消息数量的数字。原谅VB...

Private _counter As Integer = 0

Public Sub NewMessageIncrementOverlay()
  _counter += 1
  Dim displayVal = If(_counter > 9, "+", _counter.ToString)

  Dim bitm As Bitmap = New Bitmap(40, 40,
                         System.Drawing.Imaging.PixelFormat.Format32bppArgb)
  Dim g As Graphics = Graphics.FromImage(bitm)
  g.FillRectangle(System.Drawing.Brushes.Transparent, 0, 0, 40, 40)
  g.FillPie(System.Drawing.Brushes.Red, 0, 0, 40, 40, 0, 360)
  g.DrawString(displayVal, New Font("Consolas", 30, FontStyle.Bold),
               System.Drawing.Brushes.White, New PointF(3, -5))

  If TaskbarManager.IsPlatformSupported Then
    Dim icon As Icon = icon.FromHandle(bitm.GetHicon)
    TaskbarManager.Instance.SetOverlayIcon(icon, displayVal)
  End If
End Sub

I was able to create an icon dynamically with transparency for use as an overlay icon with the code below. For my program I wanted a number displaying how many new messages were queued up. Pardon the VB...

Private _counter As Integer = 0

Public Sub NewMessageIncrementOverlay()
  _counter += 1
  Dim displayVal = If(_counter > 9, "+", _counter.ToString)

  Dim bitm As Bitmap = New Bitmap(40, 40,
                         System.Drawing.Imaging.PixelFormat.Format32bppArgb)
  Dim g As Graphics = Graphics.FromImage(bitm)
  g.FillRectangle(System.Drawing.Brushes.Transparent, 0, 0, 40, 40)
  g.FillPie(System.Drawing.Brushes.Red, 0, 0, 40, 40, 0, 360)
  g.DrawString(displayVal, New Font("Consolas", 30, FontStyle.Bold),
               System.Drawing.Brushes.White, New PointF(3, -5))

  If TaskbarManager.IsPlatformSupported Then
    Dim icon As Icon = icon.FromHandle(bitm.GetHicon)
    TaskbarManager.Instance.SetOverlayIcon(icon, displayVal)
  End If
End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文