ENGINEER BLOG

ENGINEER BLOG

C# + Magick.NET で画像の背景を透明に加工してみる

こんにちは、コンサルティングサービス本部の朝日です。
最近プログラムで画像処理をすることが多かったので、
今回は、
01
の画像を
02
のように背景の白い部分を透明にする処理について書いてみたいと思います。

環境


ImageMagick を C# で使えるようにした Magick.NET というパッケージを利用しました。
NuGet でプロジェクトに追加する必要があります。

①単純に白色を透明にしてみる(失敗)


using ImageMagick;

namespace Sample {
    class Program01 {
        static void Main(string[] args) {
            using (MagickImage img = new MagickImage("c:\\temp\\01.jpg")) {
                img.ColorFuzz = new Percentage(5);
                img.Transparent(MagickColors.White);
                img.Write("c:\\temp\\03.png");
            }
        }
    }
}

(7行目) ColorFuzzであいまい度を 5% に設定して
(8行目) Transparentで白色を透明にします。

実行すると、このようになります。

03

残念ながら、内側の白い部分まで全て透明になってしまい、思ったような結果が得られないので別の方法をとります。

②透明色で塗りつぶす


using ImageMagick;

namespace Sample {
    class Program02 {
        static void Main(string[] args) {
            using (MagickImage img = new MagickImage("c:\\temp\\01.jpg")) {
                img.ColorFuzz = new Percentage(5);
                img.FloodFill(new MagickColor(0, 0, 0, 0), 0, 0);
                img.Write("c:\\temp\\04.png");
            }
        }
    }
}

(7-8行目) 左上-座標(0,0)を起点として、同じ色の部分を透明色で塗りつぶし(FloodFill)ます。

実行すると、
04
のようになります。 これでも一応成功ですが、中央下の線が少し途切れている部分から塗りつぶしが入り込んでいます。
もう少し改善します。

③ブラー(ぼかし)と塗りつぶし、合成を組み合わせる


using ImageMagick;

namespace Sample {
    class Program03 {
        static void Main(string[] args) {
            using (MagickImage img = new MagickImage("c:\\temp\\01.jpg"))
            using (MagickImage blur = img.Clone()) {
                blur.Blur(5, 5);V
                blur.Write("c:\\temp\\05a.jpg");

                blur.ColorFuzz = new Percentage(5);
                blur.FloodFill(new MagickColor(0, 0, 0, 0), 0, 0);
                blur.Write("c:\\temp\\05b.png");

                img.Alpha(AlphaOption.Set);
                img.Composite(blur, CompositeOperator.DstIn);
                img.Write("c:\\temp\\05c.png");
            }
        }
    }
}

(8行目)元画像にブラーをかけることで線を太らせます。
05a
(11-12行目)ブラーのかかった画像に対して②と同じように塗りつぶします。
05b
(15-16行目)元画像と上の画像を合成して、透明色以外の部分を残す形で切り抜いて完成です!
02
ブラーの副次的な効果で、絵の周りに少し縁取りができたのも良い感じです。

■おまけ


今回は左上-座標(0,0)を起点として塗りつぶしていますが、左上が必ずしも白(背景)ではない場合もあると思います。
その場合は、元画像に白の縁取りを付けて、そこから塗りつぶすと良いでしょう。

こんな感じのソースになります。(今回の絵の場合、実行結果は変わらないので省略します)

using ImageMagick;

namespace Sample {
    class Program04 {
        static void Main(string[] args) {
            using (MagickImage img = new MagickImage("c:\\temp\\01.jpg")) {
                img.BorderColor = MagickColors.White;
                img.Border(5);
                using (MagickImage blur = img.Clone()) {
                    blur.Blur(5, 5);
                    blur.Write("c:\\temp\\06a.jpg");

                    blur.ColorFuzz = new Percentage(5);
                    blur.FloodFill(new MagickColor(0, 0, 0, 0), 0, 0);
                    blur.Write("c:\\temp\\06b.png");

                    img.Alpha(AlphaOption.Set);
                    img.Composite(blur, CompositeOperator.DstIn);
                    img.Crop(5, 5, img.Width - 10, img.Height - 10);
                    img.Write("c:\\temp\\06c.png");
                }
            }
        }
    }
}