接下来介绍GDI+绘制图像的方法,这次主要实现的功能是图片黑白、浮雕、锐化的效果,效果图:
1、接着之前绘制字体的工程,首先在Canvas里再添加一个Image控件用来绘制图片;
2、在窗体里添加绘图的相关控制控件组;
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;
}
}
///
/// 黑白
///
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;
}
}
///
/// 浮雕
///
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;
}
}
///
/// 锐化
///
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、添加控件触发事件;
///
/// 选择图片
///
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.PixelWidth;
this.imgPic.Height = bi.PixelHeight;
Canvas.SetLeft(this.imgPic, (this.mainCanvas.ActualWidth - bi.PixelWidth) / 2);
Canvas.SetTop(this.imgPic, (this.mainCanvas.ActualHeight - bi.PixelHeight) / 2);
}
}
}
///
/// 黑白
///
private void btnBlackAndWhite_Click(object sender, RoutedEventArgs e)
{
DrawImage(ImageProcessingEffect.BlackAndWhite);
}
///
/// 浮雕
///
private void btnEmboss_Click(object sender, RoutedEventArgs e)
{
DrawImage(ImageProcessingEffect.Emboss);
}
///
/// 锐化
///
private void btnSharpening_Click(object sender, RoutedEventArgs e)
{
DrawImage(ImageProcessingEffect.Sharpening);
}
相关博文:
WPF中GDI+图形图像的绘制:(一)绘制文本——动态设置字体、大小、颜色
WPF中GDI+图形图像的绘制:(二)绘制文本——字体描边、渐变、图片叠加
WPF中GDI+图形图像的绘制:(三)绘制图像——实现黑白、浮雕、锐化效果
WPF中GDI+图形图像的绘制:(四)绘制图像——水平垂直镜像与中心旋转
WPF中GDI+图形图像的绘制:(五)绘制图像——蒙板效果
WPF中GDI+图形图像的绘制:(六)绘制图像——鼠标选中后绘制边框
WPF中GDI+图形图像的绘制:(七)绘制图像——鼠标拖动改变位置和大小
WPF中GDI+图形图像的绘制:(八)位置坐标和宽高与控件绑定展示