zoukankan      html  css  js  c++  java
  • 【WPF】ImageMagick调节图片的颜色

    需求:打开一张图片后,自由调节图片的颜色(色调)。

    思路:读取显示一张图片后,用ColorPicker取色器选择一种颜色,之后将图片的色调调节为该颜色。

    工具:

    1、图像工具 ImageMagick(.Net版)http://www.imagemagick.org/script/develop.php#dot-net 。或者在VS里Nuget搜Magick.NET-Q8-AnyCPU。

    2、WPF的取色器插件 https://www.cyotek.com/blog/colorpicker-controls-for-windows-forms。或者在VS里Nuget搜Cyotek.Windows.Forms.ColorPicker。这是设计给Form用的,但是WPF中也能用代码调用来使用。

    新建一个WPF项目,显示一张本地图片。注意图片是背景透明的,用该图表示一个图层。

    <Window x:Class="TestMagickImage.Presentation.Views.ShellWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:vm="clr-namespace:TestMagickImage.Applications.ViewModels"
            mc:Ignorable="d" Title="{Binding Title}" Icon="{StaticResource ApplicationIcon}" Width="380" Height="400">
    
        <DockPanel>
            <Menu DockPanel.Dock="Top">
                <MenuItem Header="_File">
                    <MenuItem Header="调色" Command="{Binding ShowPalletCommand}"/>
                </MenuItem>
            </Menu>
    
            <Grid>
                <Image x:Name="img" Source="/TestMagickImage;component/Presentation/Resources/Images/test.png" />
            </Grid>
        </DockPanel>
    </Window>

    这里显示的是一张捕鱼游戏的小鱼图片素材。

    在菜单项MenuItem中准备了一个按钮,按钮点击事件弹出取色器。取色器中拾取一种颜色后点击确定后,将图片调整到该色调。下面演示调整偏红色的情况。

    private void ShowPallet()
    {
        // 创建取色器(调色板)控件
        ColorPickerDialog colorPickerDialog = new ColorPickerDialog();
        colorPickerDialog.Width = 500;
        colorPickerDialog.Height = 300;
        colorPickerDialog.ShowDialog();
        
        // 查看刚才获取的颜色Color对象属性
        //MessageBox.Show(colorPickerDialog.Color.ToString());
        
        using (MagickImage image = new MagickImage(ConvertImageSourceToBitmap(shellWindow.img.Source)))
        {
            // byte --> float
            float r = colorPickerDialog.Color.R;
            
            // 仅设置Red通道
            image.Evaluate(Channels.Red, EvaluateOperator.Set, r);
    
            // 重新给Image控件赋值新图像
            shellWindow.img.Source = image.ToBitmapSource();
        }
    }
    
    
    /// <summary>
    /// ImageSource --> Bitmap
    /// </summary>
    /// <param name="imageSource"></param>
    /// <returns></returns>
    public Bitmap ConvertImageSourceToBitmap(ImageSource imageSource)
    {
        BitmapSource m = (BitmapSource)imageSource;
    
        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(m.PixelWidth, m.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
    
        System.Drawing.Imaging.BitmapData data = bmp.LockBits(
        new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
    
        m.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride); bmp.UnlockBits(data);
    
        return bmp;
    }

    调色后的效果,小鱼整体色调偏红色。因为上面的代码仅设置了图片的Red通道,所以无论颜色盘选中哪个位置,都只会取其R值使用,G值、B值未被使用上。

    但是,如果同时开放调整RGB三个通道,就会把整个图片变成单一色块!把上面代码稍微改动一下。

    using (MagickImage image = new MagickImage(ConvertImageSourceToBitmap(shellWindow.img.Source)))
    {
        // byte --> float
        float r = colorPickerDialog.Color.R;
        float g = colorPickerDialog.Color.G;
        float b = colorPickerDialog.Color.B;
        
        // 设置三个通道
        image.Evaluate(Channels.Red, EvaluateOperator.Set, r);
        image.Evaluate(Channels.Green, EvaluateOperator.Set, g);
        image.Evaluate(Channels.Blue, EvaluateOperator.Set, b);
    
        // 重新给Image控件赋值新图像
        shellWindow.img.Source = image.ToBitmapSource();
    }

    运行后的效果是一整个色块。也许有人会碰到有这种需求的情况??

  • 相关阅读:
    delphi7下调用微软的Web Services的心得
    Asp.net组件设计浅论
    STC系统烧写及STC12C5A60S2最小系统
    ENET 1.3.3 VC2005 下使用
    ENet library compilation record
    51定时器
    可靠的UDP编程(ENET库)
    ASP.NET MVC3布局页与分布页调用方式概述
    排除JQuery通过HttpGet调用WebService返回Json时“parserror”错误
    AJAX数据源协调处理思路
  • 原文地址:https://www.cnblogs.com/guxin/p/9092502.html
Copyright © 2011-2022 走看看