C#で画像の色を反転してみた

C#で画像の色を反転してみました。 手順は単純で、BitmapImageを配列にしてから配列で色を操作して、その配列をBitmapImageに変換してファイルに保存するというものです。

目次

  1. 手順
  2. 試してみた
    1. XAML
    2. コード
    3. 実行結果

手順

  1. 画像ファイルを読み込んでBitmapImageにする。

  2. BitmapImageのフォーマットをBGRAに変換する。

  3. BitmapImageから1ピクセルずつ配列にコピーする。

  4. 配列の中身を操作して色を反転する。

  5. 配列からBitmapImageを作る。

  6. ファイルに保存する。

試してみた

XAML

<Window x:Class="InverseColor.MainWindow"
        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:local="clr-namespace:InverseColor"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Image Name="img" Stretch="UniformToFill" />
    </Grid>
</Window>

Gridの中にImageを配置しました。色反転した画像を表示するためのものです。

コード

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;

namespace InverseColor
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // ファイル読み込み
            string filename = @"src.jpg";
            BitmapImage bitmapimageOriginal = new BitmapImage(new Uri(filename, UriKind.RelativeOrAbsolute));

            // BitmapImageのPixelFormatをPbgra32に変換する
            FormatConvertedBitmap bitmap = new FormatConvertedBitmap(bitmapimageOriginal, PixelFormats.Pbgra32, null, 0);

            // 画像の大きさに従った配列を作る
            int width = bitmap.PixelWidth;
            int height = bitmap.PixelHeight;
            byte[] originalPixcels = new byte[width * height * 4];
            byte[] inversedPixcels = new byte[width * height * 4];

            // BitmapSourceから配列にコピー
            int stride = (width * bitmap.Format.BitsPerPixel + 7) / 8;
            bitmap.CopyPixels(originalPixcels, stride, 0);

            // 色を反転する
            for (int x = 0; x < originalPixcels.Length; x = x + 4)
            {
                inversedPixcels[x] = (byte)(255 - originalPixcels[x]);
                inversedPixcels[x + 1] = (byte)(255 - originalPixcels[x + 1]);
                inversedPixcels[x + 2] = (byte)(255 - originalPixcels[x + 2]);
                inversedPixcels[x + 3] = originalPixcels[x + 3];
            }

            // 配列からBitmaopSourceを作る
            BitmapSource inversedBitmap = BitmapSource.Create(width, height, 96, 96, PixelFormats.Pbgra32, null, inversedPixcels, stride);

            // BitmapSourceを表示する
            img.Source = inversedBitmap;

            // BitmapSourceを保存する
            using (Stream stream = new FileStream("inv.png", FileMode.Create))
            {
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(inversedBitmap));
                encoder.Save(stream);
            }
        }
    }
}

あまり芸のあることはしてないです。

実行結果

この画像を変換してみました。 image0 変換後はこんな画像になりました。 image1 途中で画像データを配列にしてますので、配列の数値をいじることでいかようにも変換できるはずです。

公開日

広告