.net 如何使工具栏图标根据dpi缩放而不模糊?

.net 如何使工具栏图标根据dpi缩放而不模糊?,.net,winforms,.net,Winforms,我的WinForms应用程序有一个工具栏。工具栏按钮的类型为ToolStripButton。图标映像为16x16 PNG,作为资源安装 this.BtnNew.Image = Resources.NewDocument; this.BtnNew.ImageScaling = ToolStripItemImageScaling.None; 这在大多数计算机上看起来不错,但是在dpi较高的计算机上,工具栏按钮与应用程序的其余部分相比显得很小(文本按比例放大)。我想工具栏图标的规模太大 我试过了 t

我的WinForms应用程序有一个工具栏。工具栏按钮的类型为
ToolStripButton
。图标映像为16x16 PNG,作为资源安装

this.BtnNew.Image = Resources.NewDocument;
this.BtnNew.ImageScaling = ToolStripItemImageScaling.None;
这在大多数计算机上看起来不错,但是在dpi较高的计算机上,工具栏按钮与应用程序的其余部分相比显得很小(文本按比例放大)。我想工具栏图标的规模太大

我试过了

this.BtnNew.ImageScaling = ToolStripItemImageScaling.SizeToFit;
这正确地缩放了图标,但它看起来很模糊,当然,因为原始图像只有16x16像素


如何使图标根据dpi正确缩放而不模糊?使用64x64 PNG会更好吗?或者当它们被缩小时,我会得到一种不同的模糊效果吗?我可以使用svg图像吗?

缩小比放大看起来更好。通常,对于图标图像,将创建预定义的大小。为简单起见,假设宽度和高度相等。所以图像大小是{16,24,32,48,64,128,256}。使用单个64x64需要进行测试,以确定结果是否可接受

如果按钮显示一些文本,则
ToolStripButton
的高度将由其
Font
确定。如果没有文本,则仍然可以根据
Font
Graphics.Dpi
属性计算首选高度。显示的图像可以动态缩放,以适合
ToolStripItem
的首选高度。例如

public class MyToolStripButton : ToolStripButton {

    public IList<Image> Images { get; private set; }

    public MyToolStripButton(String text, IList<Image> images) : base(text) {
        Images = images.OrderBy(i => i.Height).ToList();
        ImageScaling = ToolStripItemImageScaling.None;
        RefreshImage();
    }

    protected override void OnFontChanged(EventArgs e) {
        base.OnFontChanged(e);
        RefreshImage();
    }

    public void RefreshImage() {
        int h = this.Height;
        Image bestImage = null;
        for (int i = 0; i < Images.Count; i++) {
            var img = Images[i];
            if (img.Height > h || i == Images.Count - 1) {
                bestImage = img;
                break;
            }
        }

        // scale down the image
        Image oldImage = this.Image;
        Bitmap newImage = new Bitmap(h, h);
        using (var g = Graphics.FromImage(newImage)) {
            g.DrawImage(bestImage, 0, 0, h, h);
        }

        this.Image = newImage;

        if (oldImage != null)
            oldImage.Dispose();
    }
}

        [STAThread]
        static void Main() {
            Form f = new Form();
            MenuStrip menu1 = new MenuStrip() { Dock = DockStyle.Top };
            f.Controls.Add(menu1);
            f.MainMenuStrip = menu1;

            int[] res = { 16, 32, 48, 64, 128 };
            Image[] images = new Image[res.Length];
            for (int i = 0; i < res.Length; i++) {
                Bitmap img = new Bitmap(res[i], res[i]);
                using (var g = Graphics.FromImage(img)) {
                    g.DrawEllipse(Pens.Red, 0, 0, res[i], res[i]);
                }
                images[i] = img;
            }

            MyToolStripButton btn1 = new MyToolStripButton("Button", images);
            btn1.Click += delegate {
                Font fnt = btn1.Owner.Font;
                btn1.Owner.Font = new Font(fnt.FontFamily, fnt.Size + 2f, fnt.Style);
            };
            menu1.Items.Add(btn1);
            Application.Run(f);
        }
公共类MyToolStripButton:ToolStripButton{
公共IList映像{get;private set;}
公共MyToolStripButton(字符串文本、IList图像):基(文本){
Images=Images.OrderBy(i=>i.Height.ToList();
ImageScaling=ToolStripItemImageScaling.None;
刷新图像();
}
受保护的覆盖无效OnFontChanged(事件参数e){
基数(e);
刷新图像();
}
公共图像(){
int h=此高度;
Image bestImage=null;
对于(int i=0;ih | i==Images.Count-1){
最佳图像=img;
打破
}
}
//缩小图像的比例
Image oldImage=此.Image;
位图newImage=新位图(h,h);
使用(var g=Graphics.FromImage(newImage)){
g、 DrawImage(最佳图像,0,0,h,h);
}
this.Image=newImage;
if(oldImage!=null)
Dispose();
}
}
[状态线程]
静态void Main(){
表格f=新表格();
MenuStrip menu1=new MenuStrip(){Dock=DockStyle.Top};
f、 控件。添加(菜单1);
f、 MainMenuStrip=menu1;
int[]res={16,32,48,64,128};
Image[]images=新图像[res.Length];
for(int i=0;i
如果这是DPI缩放的唯一问题,那么做得很好!试图在XP、Vista和7+@musefan上支持winforms dpi真是一件痛苦的事哦,是的。这是我写的一个简短的指南,如果它对任何人都有帮助的话