天天看点

WPF中GDI+图形图像的绘制:(三)绘制图像——实现黑白、浮雕、锐化效果

接下来介绍GDI+绘制图像的方法,这次主要实现的功能是图片黑白、浮雕、锐化的效果,效果图:

WPF中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.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);
                }            
            }
        }
        /// <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);
        }
           

相关博文:

WPF中GDI+图形图像的绘制:(一)绘制文本——动态设置字体、大小、颜色

WPF中GDI+图形图像的绘制:(二)绘制文本——字体描边、渐变、图片叠加

WPF中GDI+图形图像的绘制:(三)绘制图像——实现黑白、浮雕、锐化效果

WPF中GDI+图形图像的绘制:(四)绘制图像——水平垂直镜像与中心旋转

WPF中GDI+图形图像的绘制:(五)绘制图像——蒙板效果

WPF中GDI+图形图像的绘制:(六)绘制图像——鼠标选中后绘制边框

WPF中GDI+图形图像的绘制:(七)绘制图像——鼠标拖动改变位置和大小

WPF中GDI+图形图像的绘制:(八)位置坐标和宽高与控件绑定展示

继续阅读