简体   繁体   English

如何更改 WPF 中图像的颜色

[英]How to change color of a Image in WPF

I have a png file(8indexed and transparent)in the resource,and want to change its fore color and show it in an image.I have tried this:我在资源中有一个 png 文件(8 个索引和透明),并且想要更改它的前景色并在图像中显示它。我试过这个:

Image1.Source = new BitmapImage(new Uri($"pack://application:,,,/100.png", UriKind.Absolute));

it works fine without changing the color.它在不改变颜色的情况下工作正常。 Having Searched a lot, I combine some code all from the Internet and get the code below which looks fine,but returns strange reults.搜索了很多,我结合了一些来自互联网的代码并得到下面的代码,看起来不错,但返回奇怪的结果。

Image图片

private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // read image from base64
            const string base64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAAHqsLF6AAAAAXNSR0IArs4c6QAAAgFQTFRFAAAA////gICAVVVVQEBAMzMzVVVVSUlJQEBAOTk5MzMzRkZGQEBAOzs7Nzc3MzMzQEBAPDw8NjY2MzMzNzc3NTU1MzMzOTk5Nzc3NTU1MzMzODg4NjY2NTU1MzMzOTk5Nzc3NjY2NDQ0MzMzODg4Nzc3NTU1NTU1Nzc3NDQ0Nzc3NjY2NTU1NDQ0MzMzNTU1MzMzNTU1NTU1NDQ0NjY2NDQ0NDQ0MzMzNjY2NTU1NDQ0NTU1NDQ0NDQ0MzMzNTU1NDQ0NTU1NDQ0NDQ0MzMzNTU1NDQ0NDQ0MzMzNDQ0MzMzMzMzNTU1NDQ0MzMzMzMzNTU1NDQ0MzMzNTU1NDQ0NTU1NDQ0MzMzNDQ0MzMzMzMzNTU1NDQ0NDQ0MzMzMzMzNTU1NDQ0NDQ0MzMzNDQ0NDQ0MzMzNDQ0NDQ0NDQ0MzMzMzMzNDQ0NDQ0NDQ0MzMzNDQ0MzMzNDQ0NDQ0MzMzMzMzNDQ0NDQ0MzMzMzMzNDQ0NDQ0MzMzMzMzNDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0MzMzMzMzNDQ0MzMzMzMzNDQ0MzMzMzMzNDQ0MzMzMzMzNDQ0MzMzMzMzMzMzNDQ0MzMzNDQ0NDQ0MzMzMzMzNDQ0NDQ0MzMzMzMzMzMzNDQ0NDQ0MzMzNDQ0NDQ0MzMzMzMzMzMzNDQ0NDQ0MzMzMzMz6OxZaQAAAKp0Uk5TAAECAwQFBgcICQoLDA0ODxARExQXGBkbHB0eICEiIyQlJicoKSorMDM2ODk6Ozw/QUNERUdJSktMTU5SU1RVVlhbXV5fYWJjZGdoaWpsbW5vcXN0dnl7fYCBgoOEhYaHiImKjI2OkJSXmJqbnJ2en6Okpqepqqutr7S1tri5ury/wMHEy8zNztDR1NbX2Nrb3t/g4ePl5+jp6uzt7u/w8fL09vf4+fr7/P1teFjdAAADCklEQVRYw+1W+z9UQRSftV6pKLJ5hLYXJSpJSkXvl95IT7WlhCh6IRU9FKt3itBzw/ev7Myd3XXv3Nm9u+mjH3J+uGfOOd9zZu6ZM3OGMT1hksE70ngT/8y3a5oUn6WBfWWWtNkYn3w9wr8PLDwy4mMoFthGyZzfOKnoLaLPaIpfLn7N4q/KYcJdhIK2yIp2vVAAeaJS9gqoYvG6RRxh7NNzeVXQJW3MuxdQI4gKsaYcxhAndukg8Q7G4og3B1zpdFN7wNw/FizHI/i6ZhnQijecJWTbRH6SFUESqT5uVPcAw+pJbsPlz2+s0bQdeMd0yWYYZRGAvN5JRSo6VVPYgHRt0ILvKnskYxnQ6CVjESbzIsChE1sQKGFtVlV8Aex/oIk6qytk7E8BlccEH9gv+KN4UzFc0ou/cFEC2L3bt2wB/9bDbS6XfYxt08rhC53Ug8p1UD2/r6knyGr1OmsxrvE8IFL9h75SWI8Blb0Up8317f8ppNK5ifHJXeCnGI264CikarT55A4ajmiHSU/HsTfgFJI6CRNKwBP0ajwWSFEnYgyozlz5EKZ98LUP1imOXqG4FyUSTarkclUasTrUyvYf6Dfu7W4J4H4h+LlMLyL3r9ekH9DDZugf0OLcqfnfBb5NsYNa1kZwopYyFJbDGkj3nC3a8NjzAGctpwQq1bY8coc70WIN9lagVRtFbb05zMN5HpQnaYo95J4c6r/E3YGB3FlhpSKqizt15wspvWGcpMH00P2ddEOhTK/JGiLNgVD951KyPs6RlPcowqagbglOpzNTaw1XCJsjmyMGgT7xpiGgw+z/TCSrgobdwIgZcAvaeyrbm9Uk2T7rsMvlqtkgmiCw0BSgD3jL+fJTBDyZFjSHfAdkZRUpD4WaxTICDxhaiJ33habQ93HJKN/4Hb7n26qn/K93hlVKaz8bK3GiImTXouGfYq6C+x6vd0+5tr0rPoyfsXQv5k4dattRHqw2uH8JQfodAU8qP+zXgkeIXhppfKlK3Sxj3jTfiW1TDTD7/PUsNkMW9Buw7SzXVIvh8wAAAABJRU5ErkJggg==";
            string imagebase64 = base64.Substring(base64.IndexOf(",") + 1);
            byte[] streamBase = Convert.FromBase64String(imagebase64);
            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = new MemoryStream(streamBase);
            bitmapImage.EndInit();

            // change it to Bitmap
            Bitmap bmp = ImageSourceToBitmap(bitmapImage);

            // change color
            for (int x = 0; x < bmp.Width; x++)
            {
                for (int y = 0; y < bmp.Height; y++)
                {
                    if (bmp.GetPixel(x, y) == Color.Black)
                    {
                        bmp.SetPixel(x, y, Color.Blue);
                    }
                }
            }

            // change it back to BitmapSource
            BitmapSource bitmapSource = BitmapToBitmapImage(bmp);
            Image1.Source = bitmapSource;

        }

        // methods below
        public static System.Drawing.Bitmap ImageSourceToBitmap(ImageSource imageSource)
        {
            BitmapSource m = (BitmapSource)imageSource;

            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(m.PixelWidth, m.PixelHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); // 坑点:选Format32bppRgb将不带透明度

            System.Drawing.Imaging.BitmapData data = bmp.LockBits(
            new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);

            m.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
            bmp.UnlockBits(data);

            return bmp;
        }

        public BitmapImage BitmapToBitmapImage(Bitmap src)
        {
            MemoryStream ms = new MemoryStream();
            ((System.Drawing.Bitmap)src).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            ms.Seek(0, SeekOrigin.Begin);
            image.StreamSource = ms;
            image.EndInit();
            return image;
        }

I wonder whick part makes trouble in it.我想知道哪个部分在其中造成了麻烦。 Sorry for my poor English.对不起我的英语不好。 Any suggestion would be appreciated!任何建议将不胜感激!

Update:更新:

  1. I'm using some weather icons, and the weather website only give me some png files.我正在使用一些天气图标,而天气网站只给了我一些 png 文件。 Path/drawinggroup/streamgeometry sounds great, but it's nearly impossible for me to draw them again in WPF. Path/drawinggroup/streamgeometry 听起来不错,但我几乎不可能在 WPF 中再次绘制它们。
  2. I want to show the image directly, but Stack Overflow tells me "You need at least 10 reputation to post images."我想直接显示图片,但 Stack Overflow 告诉我“您需要至少 10 个声望才能发布图片。” emmm....嗯……
  3. Sorry to use fuzzy image, but I want to convey the massage is that not only the exact black should change to the exact blue, the lighter black should also change to lighter blue.抱歉使用模糊图像,但我想传达的信息是,不仅确切的黑色应该变成确切的蓝色,浅黑色也应该变成浅蓝色。
  4. I make an smaller reproducible example.我做了一个更小的可重现的例子。

I tried custom ShadeEfect and it's amazingly cool!我尝试了自定义ShadeEfect ,它非常酷!

hlsl code: hsl代码:

sampler2D input : register(s0);

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 color = tex2D(input, uv);
    color.b = 1;
    return color;
}

effect code:效果代码:

class ChangeColorEffect : ShaderEffect
{
    private const string _kshaderAsBase64 = @"AAP///7/HwBDVEFCHAAAAE8AAAAAA///AQAAABwAAAAAAQAASAAAADAAAAADAAAAAQACADgAAAAAAAAAaW5wdXQAq6sEAAwAAQABAAEAAAAAAAAAcHNfM18wAE1pY3Jvc29mdCAoUikgSExTTCBTaGFkZXIgQ29tcGlsZXIgMTAuMQCrUQAABQAAD6AAAIA/AAAAAAAAAAAAAAAAHwAAAgUAAIAAAAOQHwAAAgAAAJAACA+gQgAAAwAAD4AAAOSQAAjkoAEAAAIACAuAAADkgAEAAAIACASAAAAAoP//AAA=";
    private static readonly PixelShader _shader;
    
    static ChangeColorEffect()
    {
        _shader = new PixelShader();
        _shader.SetStreamSource(new MemoryStream(Convert.FromBase64String(_kshaderAsBase64)));
    }

    public ChangeColorEffect()
    {
        PixelShader = _shader;
        UpdateShaderValue(InputProperty);
    }

    public Brush Input
    {
        get { return (Brush)GetValue(InputProperty); }
        set { SetValue(InputProperty, value); }
    }

    public static readonly DependencyProperty InputProperty =
        ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(ChangeColorEffect), 0);

}

xaml code: xaml 代码:

<Image x:Name="Image1" Width="256" Height="256" Source="100.png">
    <Image.Effect>
        <local:ChangeColorEffect/>
    </Image.Effect>
</Image>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM