如何将被禁用的PictureBox作为Button灰化?

问题描述 投票:0回答:1

我在我的应用程序的主仪表板中使用Picturebox控件作为Button。当然,PictureBox有一个图片来标识Button的功能。

如果我使用普通的Button控件,当被禁用时,Button的图像会自动变灰。而使用PictureBox就不会出现这种情况。

我怎样才能产生同样的效果呢?效果 使用Picturebox。

c# picturebox
1个回答
1
投票

选项1:自定义控件(PictureBox)+ColorMatrix。

因为你不想使用按钮,因为当控件被禁用时,你的图像会变成灰色,你可以使用一个 颜色矩阵 改变 PictureBox.BackgroundImage 或(Image)转换为灰度。

您在这里看到的 GrayScale 矩阵使用众所周知的值将 Image 转换为按比例的灰度颜色表示。您可以找到对同一矩阵对象的其他解释,可能会产生不同的结果。测试一些或自己调整它可能会很有趣。

GrayScale过程是以 扩展方法因为它可能在其他情况下派上用场。它扩展了Image类,增加了一个 ToGrayScale() 方法(当然您也可以扩展Bitmap类:您只需要调用Image扩展,将Bitmap转换为Image,或者根据您的喜好调用其他方式)。


假设你有一个自定义控件,当BackgroundImage被改变时,你可以创建一个GrayScale表示并存储它。

然后覆盖 OnEnabledChanged 来改变BackgroundImage为原始或其GrayScale版本。一个简单的检查可以防止代码在内部改变BackgroundImage时生成一个新的GrayScale图像(这是一个有点简化的方法,你应该画背景来代替。我会在有能力的时候更新它)。)

GrayScale Matrix PictureBox Image

using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

[DesignerCategory("Code")]
public class ButtonPicture : PictureBox
{
    private Image m_sourceImage = null;
    private Image m_grayImage = null;

    public ButtonPicture() { }

    protected override void OnEnabledChanged(EventArgs e) {
        base.OnEnabledChanged(e);
        this.BackgroundImage = this.Enabled ? m_sourceImage : m_grayImage;
    }
        
    protected override void OnBackgroundImageChanged(EventArgs e) {
        base.OnBackgroundImageChanged(e);
        if (this.BackgroundImage == m_sourceImage || 
            this.BackgroundImage == m_grayImage) return;
        m_sourceImage = this.BackgroundImage;
        m_grayImage = m_sourceImage.ToGrayScale();
    }

    protected override void Dispose(bool disposing) {
        if (disposing) {
            m_grayImage.Dispose();
        }
        base.Dispose(disposing);
    }
}

的扩展方法。

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

public static class ImageExtensions
{
    static ColorMatrix grayMatrix = new ColorMatrix(new float[][]
    {
        new float[] { .2126f, .2126f, .2126f, 0, 0 },
        new float[] { .7152f, .7152f, .7152f, 0, 0 },
        new float[] { .0722f, .0722f, .0722f, 0, 0 },
        new float[] { 0, 0, 0, 1, 0 },
        new float[] { 0, 0, 0, 0, 1 }
    });

    public static Bitmap ToGrayScale(this Image source) {
        var grayImage = new Bitmap(source.Width, source.Height, source.PixelFormat);
        grayImage.SetResolution(source.HorizontalResolution, source.VerticalResolution);

        using (var g = Graphics.FromImage(grayImage))
        using (var attributes = new ImageAttributes()) {
            attributes.SetColorMatrix(grayMatrix);
            g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height),
                        0, 0, source.Width, source.Height, GraphicsUnit.Pixel, attributes);
            return grayImage;
        }
    }
}

方案二:ControlPaint + PictureBox.Paint事件。

您可以使用 ControlPaint.DrawImageDisabled() 画法 残疾 位图。

  • 该方法所需的图形对象由Control的 PaintEventArgs:订阅 PictureBox.Paint 事件,并通过 e.Graphics 方法的对象。
  • Image 参数可以是 PictureBox.Image 属性值。
  • 唯一的好处是,你需要的代码相当少,但默认的实现无法控制,结果是,嗯。可疑 但大概可以通用了)。

►对比左边的图片。残疾 使用ColorMatrix,右边是Image。残疾 使用ControlPaint方法。

ControlPaint PictureBox disabled Image

private void buttonPicture_Paint(object sender, PaintEventArgs e)
{
    var pict = sender as PictureBox;
    if (pict != null && (!pict.Enabled)) {
        using (var img = new Bitmap(pict.Image, pict.ClientSize)) {
            ControlPaint.DrawImageDisabled(e.Graphics, img, 0, 0, pict.BackColor);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.