WPF中GDI+图形图像的绘制:(三)绘制图像——实现黑白、浮雕、锐化效果
接下来介绍GDI+绘制图像的方法,这次主要实现的功能是图片黑白、浮雕、锐化的效果,效果图:
1、接着之前绘制字体的工程,首先在Canvas里再添加一个Image控件用来绘制图片;
<Canvas x:Name="mainCanvas" Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Background="White" Width="960" Height="720" Margin="10,5,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
ClipToBounds="True">
<Image x:Name="imgFont"></Image>
<Image x:Name="imgPic"></Image>
</Canvas>
2、在窗体里添加绘图的相关控制控件组;
<GroupBox Grid.Row="1" Grid.Column="1" Margin="10" Header="图像">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition ></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="选择图片" VerticalAlignment="Center" HorizontalAlignment="Left"></Label>
<Button x:Name="btnChooseImg" Grid.Row="0" Grid.Column="1" Content="选择" VerticalAlignment="Center" HorizontalAlignment="Left" Height="26" Width="80" Click="btnChooseImg_Click"></Button>
<StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal">
<Button x:Name="btnBlackAndWhite" Content="黑白" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left" Height="26" Width="60" Click="btnBlackAndWhite_Click"></Button>
<Button x:Name="btnEmboss" Content="浮雕" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left" Height="26" Width="60" Click="btnEmboss_Click"></Button>
<Button x:Name="btnSharpening" Content="锐化" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left" Height="26" Width="60" Click="btnSharpening_Click"></Button>
</StackPanel>
</Grid>
</GroupBox>
3、为了便于处理,添加图像处理类型枚举;
//图片处理类型枚举
public enum ImageProcessingEffect
{
Normal = 0,//原始图片
Emboss = 1,//浮雕
Sharpening = 2,//锐化
BlackAndWhite = 3//黑白
}
4、添加全局图像对象,用来记录原始图像源;
private BitmapImage imgSource;
5、添加绘图相关方法;
private void DrawImage(ImageProcessingEffect imgEffect)
{
if (this.imgSource == null) return;
BitmapImage bitmap = new BitmapImage();
switch (imgEffect)
{
case ImageProcessingEffect.BlackAndWhite://黑白
bitmap = BlackAndWhite();
this.imgPic.Source = bitmap;
break;
case ImageProcessingEffect.Emboss://浮雕
bitmap = Emboss();
this.imgPic.Source = bitmap;
break;
case ImageProcessingEffect.Sharpening://锐化
bitmap = Sharpening();
this.imgPic.Source = bitmap;
break;
default:
break;
}
}
/// <summary>
/// 黑白
/// </summary>
public BitmapImage BlackAndWhite(int opacity = 255)
{
try
{
System.Drawing.Bitmap bmap = new System.Drawing.Bitmap(this.imgSource.StreamSource);
int height = bmap.Height;
int width = bmap.Width;
System.Drawing.Color pixel;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
pixel = bmap.GetPixel(x, y);
int r, g, b, a = 0, Result = 0;
r = pixel.R;
g = pixel.G;
b = pixel.B;
int iType = 2;//这里选取加权平均值法产生黑白图像
switch (iType)
{
case 0://平均值法
Result = ((r + g + b) / 3);
break;
case 1://最大值法
Result = r > g ? r : g;
Result = Result > b ? Result : b;
break;
case 2://加权平均值法
Result = ((int)(0.7 * r) + (int)(0.2 * g) + (int)(0.1 * b));
break;
}
if (opacity < pixel.A)
{
a = opacity;
}
else
{
a = pixel.A;
}
bmap.SetPixel(x, y, System.Drawing.Color.FromArgb(a, Result, Result, Result));
}
}
return ImageHelper.BitmapToBitmapImage(bmap,System.Drawing.Imaging.ImageFormat.Png);
}
catch (Exception)
{
return this.imgSource;
}
}
/// <summary>
/// 浮雕
/// </summary>
public BitmapImage Emboss(int opacity = 255)
{
try
{
int o = opacity;
System.Drawing.Bitmap bmap = new System.Drawing.Bitmap(this.imgSource.StreamSource);
System.Drawing.Color pixel1, pixel2;
int width = bmap.Width;
int height = bmap.Height;
for (int x = 0; x < width - 1; x++)
{
for (int y = 0; y < height - 1; y++)
{
int r = 0, g = 0, b = 0, a = 0;
pixel1 = bmap.GetPixel(x, y);
pixel2 = bmap.GetPixel(x + 1, y + 1);
r = Math.Abs(pixel1.R - pixel2.R + 128);
g = Math.Abs(pixel1.G - pixel2.G + 128);
b = Math.Abs(pixel1.B - pixel2.B + 128);
a = pixel1.A;
if (a == 0)
{
opacity = a;
}
else
{
opacity = o;
}
if (r > 255)
r = 255;
if (r < 0)
r = 0;
if (g > 255)
g = 255;
if (g < 0)
g = 0;
if (b > 255)
b = 255;
if (b < 0)
b = 0;
bmap.SetPixel(x, y, System.Drawing.Color.FromArgb(opacity, r, g, b));
}
}
return ImageHelper.BitmapToBitmapImage(bmap, System.Drawing.Imaging.ImageFormat.Png);
}
catch (Exception)
{
return this.imgSource;
}
}
/// <summary>
/// 锐化
/// </summary>
public BitmapImage Sharpening(int opacity = 255)
{
try
{
System.Drawing.Bitmap bmap = new System.Drawing.Bitmap(this.imgSource.StreamSource);
int height = bmap.Height;
int width = bmap.Width;
System.Drawing.Color pixel;
//拉普拉斯模板
int[] Laplacian = { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
for (int x = 1; x < width - 1; x++)
{
for (int y = 1; y < height - 1; y++)
{
int r = 0, g = 0, b = 0, a = 0;
int Index = 0;
for (int col = -1; col <= 1; col++)
for (int row = -1; row <= 1; row++)
{
pixel = bmap.GetPixel(x + row, y + col);
r += pixel.R * Laplacian[Index];
g += pixel.G * Laplacian[Index];
b += pixel.B * Laplacian[Index];
Index++;
if (pixel.A < opacity)
{
a = pixel.A;
}
else
{
a = opacity;
}
}
//处理颜色值溢出
r = r > 255 ? 255 : r;
r = r < 0 ? 0 : r;
g = g > 255 ? 255 : g;
g = g < 0 ? 0 : g;
b = b > 255 ? 255 : b;
b = b < 0 ? 0 : b;
bmap.SetPixel(x - 1, y - 1, System.Drawing.Color.FromArgb(a, r, g, b));
}
}
return ImageHelper.BitmapToBitmapImage(bmap, System.Drawing.Imaging.ImageFormat.Png);
}
catch (Exception)
{
return this.imgSource;
}
}
6、添加控件触发事件;
/// <summary>
/// 选择图片
/// </summary>
private void btnChooseImg_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "选择图片";
openFileDialog.Filter = "图片(*.jpg,*.png,*.bmp)|*.jpg;*.png;*.bmp"; ;
openFileDialog.FileName = string.Empty;
openFileDialog.Multiselect = false;
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
BitmapImage bi = ImageHelper.LoadBitmapImageByPath(openFileDialog.FileName);
if (bi != null)
{
this.imgSource = bi;
this.imgPic.Source = bi;
this.imgPic.Width = bi.Width;
this.imgPic.Height = bi.Height;
Canvas.SetLeft(this.imgPic, (this.mainCanvas.ActualWidth - bi.Width) / 2);
Canvas.SetTop(this.imgPic, (this.mainCanvas.ActualHeight - bi.Height) / 2);
}
}
}
/// <summary>
/// 黑白
/// </summary>
private void btnBlackAndWhite_Click(object sender, RoutedEventArgs e)
{
DrawImage(ImageProcessingEffect.BlackAndWhite);
}
/// <summary>
/// 浮雕
/// </summary>
private void btnEmboss_Click(object sender, RoutedEventArgs e)
{
DrawImage(ImageProcessingEffect.Emboss);
}
/// <summary>
/// 锐化
/// </summary>
private void btnSharpening_Click(object sender, RoutedEventArgs e)
{
DrawImage(ImageProcessingEffect.Sharpening);
}