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 ...
随机推荐
- js进阶 12 jquery事件汇总
js进阶 12 jquery事件汇总 一.常用事件 页面载入事件 ready() 文档就绪事件(当 HTML 文档就绪可用时) 鼠标事件 click() 触发.或将函数绑定到指定元素的 click 事 ...
- screenX, clientX, pageX
screenX:鼠标相对屏幕左上角的水平偏移量. clientX:鼠标相对于浏览器左上角的水平偏移量,会随着滚动条的移动而移动. pageX:鼠标相对浏览器左上角的水平偏移量.不会随着滚动条的移动而移 ...
- Debian 上创建新的用户
Debian 上创建新的用户 使用Gnome的窗口界面创建 使用Linux的命令创建 添加用户: useradd -d /home/your_username -m your_username 添加密 ...
- LDD3之并发和竞态-completion(完毕量)的学习和验证
LDD3之并发和竞态-completion(完毕量)的学习和验证 首先说下測试环境: Linux2.6.32.2 Mini2440开发板 一開始难以理解书上的书面语言,这里<linux中同步样例 ...
- Android自定义组件系列【11】——实现3D立体旋转效果
今天在网上看到一篇文章写关于Android实现3D旋转(http://www.ibm.com/developerworks/cn/opensource/os-cn-android-anmt2/inde ...
- “locktype”enum type 类型重定义问题的解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 使用ado来连接数据库,结果出现这样一些编译错误: 1>f:\c++pro\iocptser\debug\msa ...
- RSA DH
https://www.cnblogs.com/hiflora/archive/2013/07/04/3171775.html http://www.ruanyifeng.com/blog/2013/ ...
- (十一)RabbitMQ消息队列-如何实现高可用
原文:(十一)RabbitMQ消息队列-如何实现高可用 在前面讲到了RabbitMQ高可用集群的搭建,但是我们知道只是集群的高可用并不能保证应用在使用消息队列时完全没有问题,例如如果应用连接的Rabb ...
- 【MySQL】15个有用的MySQL/MariaDB性能调整和优化技巧
MySQL 是一个强大的开源关系数据库管理系统(简称 RDBMS).它发布于 1995 年(20年前).它采用结构化查询语言(SQL),这可能是数据库内容管理中最流行的选择.最新的 MySQL 版本是 ...
- 《SAS编程与数据挖掘商业案例》学习笔记之十二
本次重点在:sas数据集管理 主要包含:包含数据集纵向拼接.转置.排序.比較.复制.重命名.删除等 1.append语句 注:base数据集和data两个数据集必须结构一样.避免使用force的情况, ...