WPF 修改图片颜色
原文:WPF 修改图片颜色 本文告诉大家如何修改图片的颜色,如去掉图片的蓝色 在 WPF 可以使用很多图片处理的方法,本文告诉大家的是一个图片处理,可以把处理的图片保存在文件。 在阅读本文,我假设大家是熟悉 WPF 的,至少了解 C# ,也知道图片的格式。 在 WPF 可以使用 ARBG 数组表示图片,本文修改图片颜色的方法就是使用 ARBG 数组的方法修改,修改里面的元素的值。 如我需要去掉图片的蓝色,就可以通过修改 ARBG 数组的元素,设置所有蓝色为 0 ,去掉蓝色。 首先找到一张好看的图片,放在解决方案 读取解决方案的图片 如果找不到图片,就是没有设置图片生成是 Resource 创建 WriteableBitmap 需要使用 ImageSource 所以需要先解析 使用 BitmapImage 解析文件 在读取图片之后就可以创建图片 如果读取到的图片不是 BGRA 的格式,就需要转换图片格式 使用这个代码可以把格式转为 尝试显示图片,可以看到图片还是很好看 在图片可以看到图片是使用 BGRA 的格式数组,所以只需要读取图片数组就可以修改图片 读取图片需要使用不安全代码,需要右击项目属性,点击生成,允许不安全代码。 在修改图片之前需要使用 Lock 函数,读取图片的数组长度可以使用这个代码 这里知道使用的是 BGRA 也就是一个像素使用 4 个 byte ,一个图片的像素就是 转换数组 读取颜色就是从数组拿到值 修改颜色就是修改对应的值然后设置数组,如设置蓝色是 0 去掉蓝色 设置之后需要设置图片显示 所以去掉图片的蓝色可以使用 RemoveBlue 函数,设置蓝色为 0 的方法就是读取蓝色然后修改数组 去掉蓝色的图片 现在的程序看起来还不能使用,尝试添加几个依赖属性,用来修改图片的颜色 可以点击这里下载程序 首先在 xaml 添加几个控件 注意在页面设置数据 然后打开 cs 添加代码 参见: 本文会经常更新,请阅读原文:
读取图片

            var stream = Application.GetResourceStream(new Uri("pack://application:,,,/1.jpg")).Stream;
解析文件
// 其他忽略代码
            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = stream;
            bitmapImage.EndInit();
创建图片
            var writeableBitmap = new WriteableBitmap(bitmapImage);
转换图片格式
            var formatConvertedBitmap = new FormatConvertedBitmap();
            formatConvertedBitmap.BeginInit();
            formatConvertedBitmap.Source = bitmapImage;
            formatConvertedBitmap.DestinationFormat = PixelFormats.Bgra32;
            formatConvertedBitmap.EndInit();
PixelFormats.Bgra32,需要重新创建图片            var stream = Application.GetResourceStream(new Uri("pack://application:,,,/1.jpg")).Stream;
            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = stream;
            bitmapImage.EndInit();
            var formatConvertedBitmap = new FormatConvertedBitmap();
            formatConvertedBitmap.BeginInit();
            formatConvertedBitmap.Source = bitmapImage;
            formatConvertedBitmap.DestinationFormat = PixelFormats.Bgra32;
            formatConvertedBitmap.EndInit();
            var writeableBitmap = new WriteableBitmap(formatConvertedBitmap);

读取数组
            var length = writeableBitmap.PixelWidth * writeableBitmap.PixelHeight *
                         writeableBitmap.Format.BitsPerPixel / 8;
writeableBitmap.PixelWidth * writeableBitmap.PixelHeight 。这里 writeableBitmap.Format.BitsPerPixel 就是拿到一个像素的 bit 数。            var backBuffer = (byte*) writeableBitmap.BackBuffer;
            for (int i = 0; i + 4 < length; i = i + 4)
            {
                var blue = backBuffer[i];
                var green = backBuffer[i + 1];
                var red = backBuffer[i + 2];
                var alpha = backBuffer[i + 3];
            }
            for (int i = 0; i + 4 < length; i = i + 4)
            {
                var blue = backBuffer[i];
                var green = backBuffer[i + 1];
                var red = backBuffer[i + 2];
                var alpha = backBuffer[i + 3];
                blue = 0;
                backBuffer[i] = blue;
                backBuffer[i + 1] = green;
                backBuffer[i + 2] = red;
                backBuffer[i + 3] = alpha;
            }
            writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight));
            writeableBitmap.Unlock();
        private unsafe void RemoveBlue(WriteableBitmap writeableBitmap)
        {
            writeableBitmap.Lock();
            var length = writeableBitmap.PixelWidth * writeableBitmap.PixelHeight *
                         writeableBitmap.Format.BitsPerPixel / 8;
            var backBuffer = (byte*) writeableBitmap.BackBuffer;
            for (int i = 0; i + 4 < length; i = i + 4)
            {
                var blue = backBuffer[i];
                var green = backBuffer[i + 1];
                var red = backBuffer[i + 2];
                var alpha = backBuffer[i + 3];
                blue = 0;
                backBuffer[i] = blue;
                backBuffer[i + 1] = green;
                backBuffer[i + 2] = red;
                backBuffer[i + 3] = alpha;
            }
            writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight));
            writeableBitmap.Unlock();
        }


    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="485*" />
            <ColumnDefinition Width="308*" />
        </Grid.ColumnDefinitions>
        <Image x:Name="Image" />
        <Grid Grid.Column="1">
            <Grid VerticalAlignment="Center">
                <FrameworkElement.Resources>
                    <Style TargetType="Slider">
                        <Setter Property="Width" Value="100" />
                        <Setter Property="HorizontalAlignment" Value="Center" />
                        <Setter Property="Margin" Value="10,10,10,10" />
                        <Setter Property="Minimum" Value="-255" />
                        <Setter Property="Maximum" Value="255" />
                    </Style>
                    <Style TargetType="TextBlock">
                        <Setter Property="Margin" Value="10,10,10,10" />
                        <Setter Property="HorizontalAlignment" Value="Center" />
                    </Style>
                    <local:DoubleConvert x:Key="DoubleConvert" />
                </FrameworkElement.Resources>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <TextBlock>蓝色</TextBlock>
                <TextBlock Grid.Row="1" Grid.Column="0">绿色</TextBlock>
                <TextBlock Grid.Row="2" Grid.Column="0">红色</TextBlock>
                <TextBlock Grid.Row="3" Grid.Column="0">透明度</TextBlock>
                <!-- 蓝色 -->
                <Slider Grid.Row="0" Grid.Column="1" Value="{Binding Path=Blue,Mode=TwoWay}" />
                <!-- 绿色 -->
                <Slider Grid.Row="1" Grid.Column="1" Value="{Binding Path=Green,Mode=TwoWay}" />
                <!-- 红色 -->
                <Slider Grid.Row="2" Grid.Column="1" Value="{Binding Path=Red,Mode=TwoWay}" />
                <!-- 透明度 -->
                <Slider Grid.Row="3" Grid.Column="1" Value="{Binding Path=Alpha,Mode=TwoWay}" />
                <!-- 蓝色 -->
                <TextBlock Grid.Row="0" Grid.Column="2"
                           Text="{Binding Path=Blue,Mode=OneWay,Converter={StaticResource DoubleConvert}}" />
                <!-- 绿色 -->
                <TextBlock Grid.Row="1" Grid.Column="2"
                           Text="{Binding Path=Green,Mode=OneWay,Converter={StaticResource DoubleConvert}}" />
                <!-- 红色 -->
                <TextBlock Grid.Row="2" Grid.Column="2"
                           Text="{Binding Path=Red,Mode=OneWay,Converter={StaticResource DoubleConvert}}" />
                <!-- 透明度 -->
                <TextBlock Grid.Row="3" Grid.Column="2"
                           Text="{Binding Path=Alpha,Mode=OneWay,Converter={StaticResource DoubleConvert}}" />
            </Grid>
            <Grid VerticalAlignment="Bottom">
                <Button Margin="10,10,10,10" Content="替换图片" Click="Button_OnClick" />
            </Grid>
        </Grid>
    </Grid>
DataContext="{Binding RelativeSource={RelativeSource Self}}"
      private WriteableBitmap _writeableBitmap;
        public MainWindow()
        {
            InitializeComponent();
            Image.Margin = new Thickness(10, 10, 10, 10);
            var stream = Application.GetResourceStream(new Uri("pack://application:,,,/1.jpg")).Stream;
            ChangeImage(stream);
            DataContext = this;
        }
        public static readonly DependencyProperty BlueProperty = DependencyProperty.Register(
            "Blue", typeof(double), typeof(MainWindow),
            new PropertyMetadata(default(double), (s, e) => ((MainWindow) s).ChangeArray()));
        public double Blue
        {
            get { return (double) GetValue(BlueProperty); }
            set { SetValue(BlueProperty, value); }
        }
        public static readonly DependencyProperty GreenProperty = DependencyProperty.Register(
            "Green", typeof(double), typeof(MainWindow),
            new PropertyMetadata(default(double), (s, e) => ((MainWindow) s).ChangeArray()));
        public double Green
        {
            get { return (double) GetValue(GreenProperty); }
            set { SetValue(GreenProperty, value); }
        }
        public static readonly DependencyProperty RedProperty = DependencyProperty.Register(
            "Red", typeof(double), typeof(MainWindow),
            new PropertyMetadata(default(double), (s, e) => ((MainWindow) s).ChangeArray()));
        public double Red
        {
            get { return (double) GetValue(RedProperty); }
            set { SetValue(RedProperty, value); }
        }
        public static readonly DependencyProperty AlphaProperty = DependencyProperty.Register(
            "Alpha", typeof(double), typeof(MainWindow),
            new PropertyMetadata(default(double), (s, e) => ((MainWindow) s).ChangeArray()));
        public double Alpha
        {
            get { return (double) GetValue(AlphaProperty); }
            set { SetValue(AlphaProperty, value); }
        }
        private void ChangeImage(Stream stream)
        {
            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = stream;
            bitmapImage.EndInit();
            var formatConvertedBitmap = new FormatConvertedBitmap();
            formatConvertedBitmap.BeginInit();
            formatConvertedBitmap.Source = bitmapImage;
            formatConvertedBitmap.DestinationFormat = PixelFormats.Bgra32;
            formatConvertedBitmap.EndInit();
            _writeableBitmap = new WriteableBitmap(formatConvertedBitmap);
            ChangeArray();
        }
        private unsafe void ChangeArray()
        {
            var writeableBitmap = _writeableBitmap;
            if (writeableBitmap == null)
            {
                return;
            }
            writeableBitmap.Lock();
            var length = writeableBitmap.PixelWidth * writeableBitmap.PixelHeight *
                         writeableBitmap.Format.BitsPerPixel / 8;
            var backBuffer = (byte*) writeableBitmap.BackBuffer;
            var byteList = new byte[length];
            for (int i = 0; i + 4 < length; i = i + 4)
            {
                var blue = backBuffer[i];
                var green = backBuffer[i + 1];
                var red = backBuffer[i + 2];
                var alpha = backBuffer[i + 3];
                blue += (byte) Blue;
                green += (byte) Green;
                red += (byte) Red;
                alpha += (byte) Alpha;
                byteList[i] = blue;
                byteList[i + 1] = green;
                byteList[i + 2] = red;
                byteList[i + 3] = alpha;
            }
            writeableBitmap.Unlock();
            writeableBitmap = new WriteableBitmap(writeableBitmap.PixelWidth, writeableBitmap.PixelHeight, 96, 96,
                writeableBitmap.Format, writeableBitmap.Palette);
            writeableBitmap.Lock();
            writeableBitmap.WritePixels(new Int32Rect(0, 0, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight),
                byteList, writeableBitmap.BackBufferStride, 0);
            writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight));
            writeableBitmap.Unlock();
            Image.Source = writeableBitmap;
        }
        private void Button_OnClick(object sender, RoutedEventArgs e)
        {
            var openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "jpg(*.jpg)|*.jpg";
            if (openFileDialog.ShowDialog() == true)
            {
                var stream = openFileDialog.OpenFile();
                ChangeImage(stream);
            }
        }
    public class DoubleConvert : IValueConverter
    {
        /// <inheritdoc />
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is double n)
            {
                return n.ToString("0.00");
            }
            return DependencyProperty.UnsetValue;
        }
        /// <inheritdoc />
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
    https://lindexi.gitee.io/lindexi/post/WPF-%E4%BF%AE%E6%94%B9%E5%9B%BE%E7%89%87%E9%A2%9C%E8%89%B2.html
    ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
    本作品采用
    知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议
    进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:
    https://lindexi.gitee.io
    ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请
    与我联系
    。
WPF 修改图片颜色的更多相关文章
- xml代码修改图片颜色
		<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http ... 
- Android动态修改图片颜色的实现方式分析
		版权声明:本文为博主原创文章,未经博主允许不得转载. 1.修改色相.饱和度.亮度 参看:http://blog.csdn.NET/sjf0115/article/details/7267063 2.使 ... 
- c# 快速修改图片颜色
		public static void ChangeColour(this Bitmap bmp, byte inColourR, byte inColourG, byte inColourB, byt ... 
- 2018-8-10-WPF-修改图片颜色
		title author date CreateTime categories WPF 修改图片颜色 lindexi 2018-08-10 19:16:53 +0800 2018-07-03 15:4 ... 
- 利用Photoshop修改图片以达到投稿要求
		摘自:http://www.dxy.cn/bbs/thread/8602152#8602152 利用Photoshop修改图片以达到投稿要求 软件版本为Photoshop CS V8.0.1(中文版) ... 
- tabbarItem字体及图片颜色设置
		tabbarItem设置图片后运行往往与我们原始图片颜色有出入,这是因为在默认情况下,未选中状态图片和字体颜色为灰色,选中状态下图片和字体颜色为蓝色. UIImage 在呈现(render)时会选 ... 
- Android--ColorMatrix改变图片颜色
		前言 本篇博客讲解如何通过改变图片像素点RGB的值的方式,在Android中改变图片的颜色.在最后将以一个简单的Demo来作为演示. 本篇博客的主要内容: ColorMatrix 使用ColorMat ... 
- IOS: 使用imageIO获取和修改图片的exif信息
		使用imageIO获取和修改图片的exif信息 一幅图片除了包含我们能看见的像素信息,背后还包含了拍摄时间,光圈大小,曝光等信息.UIImage类将这些细节信息都隐藏了起来,只提供我们关心的图片尺寸, ... 
- word中批量修改图片大小的两个方法
		前言: 对于把ppt的内容拷贝到word中: 对ppt的一页进行复制,然后粘贴到word中 如果要的是ppt运行过程中的内容,在qq运行的情况下,按Ctrl+Alt+A截屏,按勾,然后可以直接粘贴到w ... 
随机推荐
- uvalive 6393(uva 1572) Self-Assembly 拓扑排序
			题意: 给出一些正方形,这些正方形的每一条边都有一个标号.这些标号有两种形式:1.一个大写字母+一个加减号(如:A+, B-, A-......), 2.两个0(如:00):这些正方形能够任意翻转和旋 ... 
- 辛星彻底帮您解决CSS中的浮动问题
			浮动,是CSS布局中必须经过的一道坎,假设不熟悉浮动.那么CSS的布局就如同空中楼阁,而谈到浮动,很多其它的是和div相结合,div是一个块级元素.这个我前面的博文有介绍,假设大家喜欢我的风格,能够搜 ... 
- POS 60域用法
			版权声明:本文为博主原创文章,未经博主允许不得转载. 自定义域(Reserved Private) 1.变量属性 N...17(LLLVAR),3个字节的长度值+最大17个字节的数字字符域. 压缩时用 ... 
- 关于db2的一点记录
			近期听搞db2的兄弟说:db2数据库软件的license 不区分平台(os). 先记下来.像db2这么高大上的软件,接触的机会是比較少的. 另外:db2 的license是须要打的,不打的话,超过一段 ... 
- Cocos2d-X开发中国象棋《八》走棋
			在上一节中实现了新局,至此中国象棋的准备工作差点儿相同都完毕了,在接下来的博客中将介绍玩家的走棋和一些游戏属性的设置,今天先介绍走棋和走棋规则 老规则,先看走棋的效果图,然后依据效果图一步一步分析游戏 ... 
- POJ 题目2506Tiling(大数)
			Tiling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8128 Accepted: 3941 Descriptio ... 
- Longest Increasing Subsequences(最长递增子序列)的两种DP实现
			一.本文内容 最长递增子序列的两种动态规划算法实现,O(n^2)及O(nlogn). 二.问题描述 最长递增子序列:给定一个序列,从该序列找出最长的 升序/递增 子序列. 特点:1.子序列不要 ... 
- 【53.57%】【codeforces 722D】Generating Sets
			time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ... 
- [TypeScript] Understand lookup types in TypeScript
			Lookup types, introduced in TypeScript 2.1, allow us to dynamically create types based on the proper ... 
- form表单上传附件的几种方法
			问题描述:在网页开发过程中,当需要上传附件(图片,音频,视频等)时,常规方法是使用form表单进行提交,这里总结一下form表单提交的几种方法. 参考地址:http://www.cnblogs.com ... 
