2011-08-16 88 views
3

我有一個.ico文件,其中.png文件具有要應用於圖標的疊加層。我在這方面很缺乏經驗,所以我設法從互聯網上獲得一些代碼,直到我有一些幾乎可行的東西。向圖標添加疊加層時的透明度問題

問題是透明度丟失,並用白色代替。

此外,我認爲顏色範圍減少。我添加了一些調試代碼(註釋掉)以保存2個階段的圖標。當我在VS 2010的第一階段對它進行編輯時,顏色托盤有16種顏色,stage1。還有更多。

似乎是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; 
} 
+0

這是用於一個WPF應用程序? –

+0

使用此圖標的部分是WinForms,但稍後我會調用WPF窗口。 WinForms部分在系統托盤中顯示一個圖標 - 正是這個圖標出現問題。謝謝。 –

+0

GetHicon()是問題所在,它使用了一個非常原始的算法。它使用只有16個原色的調色板。除非圖像非常簡單,否則結果總是令人失望。這是一個難題,我不知道有什麼完美的解決方案。 –

回答

0

我能與透明度用作與下面的代碼覆蓋圖標動態地創建一個圖標。對於我的程序,我想要一個數字來顯示排隊的新消息數量。赦免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