notifyicon image looks terrible once image ends up in system tray
I am using Visual Studio 2010, C#, on Windows 7.
I have added a notify control to my project and set it to an icon I have imported to the project. The icon image is really good looking if I just preview it, but once I run my code and see it in the system tray, then it's really terrible, like the sides are dotted instead of straight lines and so on. I have tried 16x16, 24x24, 32x32 and 48x48 of the same file but I am having terrible results.
Have I m开发者_如何学运维issed anything?
myNotifyIcon.Icon = SysDir.Properties.Resources.icon2_32_ico_rgba;
The problem with directly using the icon in your resources is that instead of choosing the right icon version in you icon file, the framework simply scales the default icon version to whatever size the notification area needs. That's why you are seeing jagged edges.
To get the best quality, you'll need to choose the right size in your icon by yourself.
First, instead of directly setting your NotifyIcon.Icon
to an icon in your resources, create a new Icon
instance. Doing so will allow you to choose a specific icon size in your icon resource. Using SystemInformation.SmallIconSize
will get you the size the notification area needs.
So :
myNotifyIcon.Icon = new Icon(Properties.Resources.MyIcon, SystemInformation.SmallIconSize);
Now, SystemInformation.SmallIconSize
always returns the right icon size, but only if your application is DPI-aware (otherwise, it always returns 16). If your application isn't DPI-aware, and it is used on a system where DPI-scaling is enabled, the line above will select the 16x16 icon in your resource, at it'll be scaled up to whatever size the notification area needs (in other words, ugly icon).
By making your app DPI-aware, SystemInformation.SmallIconSize
will return the right size, taking into account DPI-scaling. For instance, if DPI-scaling is at 150%, SystemInformation.SmallIconSize
will return 24 (16 × 1.5).
To make your app DPI-aware, simply add this to your app.manifest, inside the <asmv1:assembly>
tag:
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
Edit:
The info I am linking seems to be suspect at this point. Try it out, but if it isn't working, then I suggest you edit your question to post screenshots of all your experiments (each icon size and how it gets scaled).
Original:
32x32x256 is the right size and color depth according to this link:
http://www.hhhh.org/cloister/csharp/icons/
But you have to be very careful when constructing that image:
- Take a 16x16x256 image, and get it to look nice
- Double it to 32x32 (careful not to blur or resample if doing this in a paint program)
The reason is that Windows will "resize" the 32x32 image to 16x16 by simply throwing away 3/4 of the pixels. The link above demonstrates this phenomenon with a couple screenshots:
Before:
After:
I'm not sure how much of the color-depth pickyness (256 colors only?)/resampling issues are still true on Windows 7, but it certainly seems to be the case on XP.
I use NotifyIcon
in a C# WinForms application and no matter what the icon I use contains, after 2 resolution changes it ends up blurry.
My best guess is, that windows doesn't actually rescale the original every time but rescales the (already rescaled) version from the icon cache.
The only solution I found so far was setting the icon again after a resolution/dpi change:
SystemEvents.DisplaySettingsChanged += (sender, eventArgs) => {
trayIcon.Icon = MyIcon;
};
I tried all kind of resolutions and bit depths in the icons but they all got blurred eventually. Now I only use a single 16x16 32b image in the icon and so far it works great on all tested displays.
精彩评论