【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();
}

運行后的效果是一整個色塊。也許有人會碰到有這種需求的情況??

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM